/*


    thread.cc

    C++ source for thread class test file.

    Copyright (C) 1999,2001 by Matt Roberts, KK5JY,
    All rights reserved.


*/


#include <string.h>
#include <cstring>
#include <iostream.h>
#include <unistd.h>
#include <cstdio>

#include <my++/thread.h>

using namespace my;


/*
 *
 *   report (const char *) -- function to print output in a
 *   thread-safe manner
 *
 */

void report (const char *message) {
	/* mutex to protect the I/O routine */
    static mutex m;

    m.lock ();                    /* lock the routine   */
    fprintf (stdout, message);    /* print the message  */
    m.unlock ();                  /* unlock the routine */
}


/*
 *
 *   class MyWriteTask
 *
 *   my::thread-derived class to implement a simple task
 *
 */

class MyWriteTask : public thread {
		int mwt_id;

	public:
		MyWriteTask (int id) : mwt_id(id), thread ((void*)(&id)) { };
		~MyWriteTask (void) { };

		void *run (void *args);

		static void wait (void);
};

void MyWriteTask::wait (void) {
	static mutex lm;

	lm.lock();
	usleep (100000);
	lm.unlock();
}


void *MyWriteTask::run (void *args) {
    int i = 0;
    int id = *((int *)(args));
    char buffer [80];
    sprintf (buffer, "Thread %d execution begins\n", id);
    report (buffer);

    while (i < 10) {
       sprintf (buffer, "Thread %d running: %d seconds expired\n", id, i);
       report (buffer);
       wait ();
       i += 1;
    }

	return 0;
}


/*
 *
 *    main (...)
 *
 */

int main (int argc, char **argv) {
    report ("Create thread objects.\n");
    MyWriteTask task1(1);
	MyWriteTask	task2(2);
	MyWriteTask task3(3);
	MyWriteTask task4(4);
    MyWriteTask task5(5);

	report ("Start thread objects.\n");

	report ("  + start thread 1\n");
	task1.start();
	report ("  + start thread 2\n");
	task2.start();
	report ("  + start thread 3\n");
	task3.start();
	report ("  + start thread 4\n");
	task3.start();
	report ("  + start thread 5\n");
	task3.start();

	report ("Join threads.\n");
    task1.join();
    task2.join();
    task3.join();
    task4.join();
    task5.join();

    report ("All threads have exited.\n");
	return 0;
}
