#include "xheaders.h"
#include XNamedPipeServer_i
#include XThread_i
#include XEventSemaphore_i
#include XString_i
#include XSemaphoreException_i

#include <process.h>
#include <stdlib.h>
#include <stdio.h>

XString semName;

//we derive a class
class MyServer: public XNamedPipeServer
{
   public:
      MyServer();
      void Start( int );
};

static int c = 0;

//the thread-starting function
// TBO
#ifndef __WATCOMC__
void _Optlink StartFunction( void * arg)
#else
void StartFunction( void * arg)
#endif
{
   c += 10;
   MyServer * s = (MyServer*) arg;
   s->Start( c );
}


//create the server and open a pipe
MyServer :: MyServer(): XNamedPipeServer() 
{
   LONG res;
	BOOL created = FALSE;

	XEventSemaphore * sem = NULL;
	if( semName.GetLength() == 0) 		//no thread earlier started
	{												//we set a semaphore so the next thread waits with 
    	semName = "sample9";	//initalisation until this thread has started
		created = TRUE;
		sem = new XEventSemaphore( "sample9", TRUE, FALSE);
	}
	else		//a semaphor is set, another thread was started earlier than this.
	{	
				//this thread must wait until the earlier thread has finished intialisation
    	try	//try if the semaphore is working
		{
			sem = new XEventSemaphore( "sample9" );	//try to open the semaphore 
			sem->Wait(-1);									//wait until the semaphore gets post
		}
		catch( XSemaphoreException& e)	//if an exception is thrown the semaphore is closed
		{											//start to init this thread (no error-handling needed)
		}
	}
   if( (res = Open( "Sample9Pipe", XNPIPE_ACCESS_DUPLEX, XNPIPE_WAIT|XNPIPE_TYPE_BYTE|XNPIPE_READMODE_BYTE, 2 )) != 0)
   {
      printf( "cannot open server: %i", res);
      exit(0);
   }

   //every server is a single thread, because we use simple threads
   //and not the window-api, this simple method is recommended
   _beginthread( StartFunction, NULL, 20000, (void*) this);

	if( sem )
	{
    	if(created)	//if this thread created the semaphore, post so other threads dont wait any longer
			sem->Post();
		delete sem; //close the semaphore
	}
}


//start this server
void MyServer :: Start( int id )
{   
   printf("server %i started, id = %i\n", id/10, id);
   LONG res;

   //wait for a connect
   Connect();

   while(1)
   {
		//client is killed?
      if( GetState() == XNPIPE_STATE_CLOSING)
		{
			//clear connection
			DisConnect();     
			//wait for the next client          
			if( (res = Connect()) != 0)
			{
				printf( "cannot connect: %i id=%i", res, id);
				exit(0);
			} 
		}

		//we have a client
		if( GetState() == XNPIPE_STATE_CONNECTED)         
		{
			//write some data
			LONG i;
			for(i=0; i < 10000; i++)
				Write( i + id);
			ResetBuffer();
		}
	}
}


void main ( void)
{
   LONG res;
   printf( "press Ctrl+C to stop the server\n");

   //in this case we start two servers 
	try
	{
	   MyServer server1;
	   MyServer server2;

	   //let the servers work
	   XThread :: RunThreads();
	}
	catch( XSemaphoreException& e)
	{
	   printf("\nA semaphore-exception was thrown!\n");
		e.PrintError();
	}
	catch( XException& e)
	{
		printf("\nA standard-exception was thrown!\n");
		e.PrintError();
	}
}
