// test_i.cpp,v 1.1 1999/12/21 23:51:55 irfan Exp // ================================================================ // // = FILENAME // test_i.cpp // // = DESCRIPTION // This is the implementation of the test interface // that uses ACS callbacks. // Has been written taking the AMI example and changing // as little as possible to use ACS callbacks instead of AMI // callbacks. // To make the example really asynchronous, we use a reactor // that handles the replies to be sent to the client. // This is then also a simple example of the usage of the reactor. // // = AUTHOR // G.Chiozzi, R.Lemke (Irfan Pyarali for the AMI example) // // ================================================================ #include "test_i.h" /* GCH/RLE * * We include here baci and thread functionality from ACE */ #include "baci.h" #include "ace/Thread.h" /* GCH/RLE * * The ACE_Reactor is a static data member, i.e. * it is a singleton for the class, as well as the * thread where it runs. * Since the "real" reactor must be instantiated in the * thread worker function, we have here just a pointer. */ ACE_Reactor *test_i::rtc = NULL; /* GCH/RLE * * This is the event handler class whose handle_timeout() * method is used to send replies to the client */ class testHandler : public ACE_Event_Handler { public: virtual int handle_timeout(const ACE_Time_Value &tv, const void *arg) { ACE_TRY_NEW_ENV { Completion comp; CBDescOut descOut; test_i::cbData *data = (test_i::cbData*)arg; ACE_DEBUG ((LM_DEBUG, "server (async): Completed iteration %d @ %T\n", data->reply_number)); data->cb->done(data->reply_number, comp, descOut, ACE_TRY_ENV); ACE_TRY_CHECK; delete data; } ACE_CATCHANY { ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Exception caught:"); return -1; } ACE_ENDTRY; return 0; } }; /* GCH/RLE * * The constructor spawns the reactor's thread * when the first instance is created */ test_i::test_i (CORBA::ORB_ptr orb) : orb_ (CORBA::ORB::_duplicate (orb)) { ACE_DEBUG((LM_DEBUG,"Creating servant. Spawning reactor thread\n")); if(rtc==NULL) { if (ACE_Thread::spawn((ACE_THR_FUNC)worker) == -1) ACE_DEBUG((LM_DEBUG,"Error in spawning thread\n")); } } /* GCH/RLE * * The worker function for the thread just allows the * reactor to pickup and handle the queued events */ void* test_i::worker(void *arguments) { ACE_Reactor reactor; rtc = &reactor; ACE_DEBUG ((LM_DEBUG, "worker : Starting reactor\n")); while (true) { reactor.handle_events(); } ACE_DEBUG ((LM_DEBUG, "worker : Close reactor\n")); return 0; } void test_i::method (CORBA::ULong request_number, CORBA::ULong_out reply_number, CORBA::Environment &) ACE_THROW_SPEC (()) { if (request_number == 1) sleep(5); ACE_DEBUG ((LM_DEBUG, "server: Iteration %d @ %T\n", request_number)); reply_number = request_number; } /* GCH/RLE * * This is the asynchronous method. * To be truly asynchronous it just installs a timer * that will send back the reply to the client and * returns immediately. */ void test_i::method_async (CORBA::ULong request_number, ESO::CBlong_ptr cb, const ESO::CBDescIn & desc, CORBA::Environment &) ACE_THROW_SPEC (()) { int sleepTime = 1; if (request_number == 1) sleepTime = 5; ACE_DEBUG ((LM_DEBUG, "server (async): Iteration %d @ %T, waiting %d sec\n", request_number, sleepTime)); cbData *data = new cbData; data->reply_number = request_number; data->cb = ESO::CBlong::_duplicate(cb); rtc->schedule_timer(new testHandler, (const void*)data, ACE_Time_Value(sleepTime)); }; #ifdef additional void test_i::additional_method (CORBA::ULong request_number, CORBA::ULong_out reply_number, CORBA::Environment &) ACE_THROW_SPEC (()) { if (request_number == 1) sleep(5); // align to next full second // ACE_Time_Value txv = ACE_OS::gettimeofday (); // usleep(1000000-txv.usec ()); // ACE_DEBUG ((LM_DEBUG, "server: Iteration %d @ %T\n", request_number)); reply_number = request_number; } /* GCH/RLE * * This is the asynchronous method. * To be truly asynchronous it just installs a timer * that will send back the reply to the client and * returns immediately. */ void test_i::additional_method_async (CORBA::ULong request_number, ESO::CBlong_ptr cb, const ESO::CBDescIn & desc, CORBA::Environment &) ACE_THROW_SPEC (()) { int sleepTime = 1; if (request_number == 1) sleepTime = 5; ACE_DEBUG ((LM_DEBUG, "server (async): Iteration %d @ %T, waiting %d sec\n", request_number, sleepTime)); cbData *data = new cbData; data->reply_number = request_number; data->cb = ESO::CBlong::_duplicate(cb); rtc->schedule_timer(new testHandler, (const void*)data, ACE_Time_Value(sleepTime)); }; #endif void test_i::shutdown (CORBA::Environment &ACE_TRY_ENV) ACE_THROW_SPEC (()) { this->orb_->shutdown (0, ACE_TRY_ENV); }