int main(int argc, char* argv[]) { Logger *logger = new Logger; int n_loops = 10; ACE_Future<u_long> logresult; ACE_Future<const char*> name; logger->open(0); for (size_t i = 0; i < n_loops; i++) { char* msg = new char[50]; ACE_DEBUG((LM_DEBUG, "Issuing a non-blocking logging call\n")); ACE_OS::sprintf(msg, "This is iteration %d", i); logresult = logger->logMsg(msg); } ACE_DEBUG((LM_DEBUG, "(%t) Invoked all the log calls and can now continue with other work \n")); name = logger->name(); if(name.ready()) ACE_DEBUG((LM_DEBUG, "Name is ready! \n")); else ACE_DEBUG((LM_DEBUG, "Blocking till I get the result of that call \n")); const char* task_name; name.get(task_name); ACE_DEBUG((LM_DEBUG, "(%t)==> The name of the task is: %s\n\n\n", task_name)); ACE_Thread_Manager::instance()->wait(); }
int Method_Request_name::call (void) { // Dispatch the Servant's operation and store the result into the // Future. return future_result_.set (scheduler_->name_i ()); }
virtual void update (const ACE_Future<ACE_CString*> & future) { ACE_CString *result = 0; // Block for the result. future.get (result); ACE_DEBUG ((LM_INFO, ACE_TEXT("%C\n"), result->c_str ())); delete result; }
int Client_Handler::process(unsigned char* buf,size_t buf_len) { //variable used to store the response to client int return_id; stringstream debug; ACE_Future<int> result; size_t bytes_read; switch ( (bytes_read = this->peer().recv_n (buf, buf_len)) ) { case -1: ACE_ERROR_RETURN ((LM_ERROR, "bad read\n", "client"), 0); case 0: ACE_ERROR_RETURN ((LM_ERROR, "closing daemon (fd = %d)\n", this->get_handle ()), -1); default: if (bytes_read == buf_len) { connectionMsgBlock *cmb = new connectionMsgBlock(buf); if ( srv_counter++ < 10 && cmb->isValid() == true) { result = parentContest->processor->process(cmb); // cout << "result.ready() = " << result.ready() << endl; result.get(return_id); peer().send_n(&return_id, sizeof(int)); delete cmb; return -1; } else { debug.str(""); debug << "ERROR CRC:"<<srv_counter<<endl; parentContest->logger->logMsg(debug.str()); peer().send_n(&(return_id = ID_CRC_ERROR), sizeof(int)); ACE_OS::sleep(1); return 0; } } else return 0; } }
template <class T> int ACE_Future_Set<T>::insert (ACE_Future<T> &future) { FUTURE_HOLDER *future_holder; ACE_NEW_RETURN (future_holder, FUTURE_HOLDER (future), -1); FUTURE_REP *future_rep = future.get_rep (); int result = this->future_map_.bind (future_rep, future_holder); // If a new map entry was created, then attach to the future, // otherwise we were already attached to the future or some error // occurred so just delete the future holder. if ( result == 0 ) // Attach ourself to the ACE_Futures list of observer future.attach (this); else delete future_holder; return result; }
int run_main (int, ACE_TCHAR *[]) { ACE_START_TEST (ACE_TEXT ("Future_Test")); #if defined (ACE_HAS_THREADS) // @@ Should make these be <auto_ptr>s... Prime_Scheduler *andres, *peter, *helmut, *matias; // Create active objects.. ACE_NEW_RETURN (andres, Prime_Scheduler (ACE_TEXT ("andres")), -1); int result = andres->open (); ACE_TEST_ASSERT (result != -1); ACE_NEW_RETURN (peter, Prime_Scheduler (ACE_TEXT ("peter")), -1); result = peter->open (); ACE_TEST_ASSERT (result != -1); ACE_NEW_RETURN (helmut, Prime_Scheduler (ACE_TEXT ("helmut")), -1); result = helmut->open (); ACE_TEST_ASSERT (result != -1); // Matias passes all asynchronous method calls on to Andres... ACE_NEW_RETURN (matias, Prime_Scheduler (ACE_TEXT ("matias"), andres), -1); result = matias->open (); ACE_TEST_ASSERT (result != -1); for (int i = 0; i < n_loops; i++) { { ACE_Future<u_long> fresulta; ACE_Future<u_long> fresultb; ACE_Future<u_long> fresultc; ACE_Future<u_long> fresultd; ACE_Future<u_long> fresulte; ACE_Future<const ACE_TCHAR *> fname; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) going to do a non-blocking call\n"))); // Spawn off the methods, which run in a separate thread as // active object invocations. fresulta = andres->work (9013); fresultb = peter->work (9013); fresultc = helmut->work (9013); fresultd = matias->work (9013); fname = andres->name (); // See if the result is available... if (fresulta.ready ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. work is ready.....\n"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) non-blocking call done... now blocking...\n"))); // Save the result of fresulta. fresulte = fresulta; if (i % 3 == 0) { // Every 3rd time... disconnect the futures... but // "fresulte" should still contain the result... fresulta.cancel (10ul); fresultb.cancel (20ul); fresultc.cancel (30ul); fresultd.cancel (40ul); } u_long resulta = 0, resultb = 0, resultc = 0, resultd = 0, resulte = 0; fresulta.get (resulta); fresultb.get (resultb); fresultc.get (resultc); fresultd.get (resultd); fresulte.get (resulte); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) result a %u\n") ACE_TEXT ("(%t) result b %u\n") ACE_TEXT ("(%t) result c %u\n") ACE_TEXT ("(%t) result d %u\n") ACE_TEXT ("(%t) result e %u\n"), (u_int) resulta, (u_int) resultb, (u_int) resultc, (u_int) resultd, (u_int) resulte)); const ACE_TCHAR *name = 0; fname.get (name); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) name %s\n"), name)); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) task_count %d future_count %d ") ACE_TEXT ("capsule_count %d method_request_count %d\n"), task_count.value (), future_count.value (), capsule_count.value (), method_request_count.value ())); } // Close things down. andres->end (); peter->end (); helmut->end (); matias->end (); ACE_Thread_Manager::instance ()->wait (); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) task_count %d future_count %d ") ACE_TEXT ("capsule_count %d method_request_count %d\n"), task_count.value (), future_count.value (), capsule_count.value (), method_request_count.value ())); { // Check if set then get works, older versions of <ACE_Future> // will lock forever (or until the timer expires), will use a // small timer value to avoid blocking the process. ACE_Future<int> f1; f1.set (100); // Note you need to use absolute time, not relative time. ACE_Time_Value timeout (ACE_OS::gettimeofday () + ACE_Time_Value (10)); int value = 0; if (f1.get (value, &timeout) == 0 && value == 100) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Ace_Future<T>::Set followed by Ace_Future<T>::Get works.\n"))); else ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Future<T>::Set followed by Ace_Future<T>::Get does ") ACE_TEXT ("not work, broken Ace_Future<> implementation.\n"))); } { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Checking if Ace_Future<T>::operator= is implemented ") ACE_TEXT ("incorrectly this might crash the program.\n"))); ACE_Future<int> f1; { // To ensure that a rep object is created. ACE_Future<int> f2 (f1); } // Now it is one ACE_Future<int> referencing the rep instance ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("0.\n"))); //Check that self assignment works. f1 = f1; // Is there any repesentation left, and if so what is the ref // count older ACE_Future<> implementations have deleted the rep // instance at this moment // The stuff below might crash the process if the <operator=> // implementation was bad. int value = 0; ACE_Time_Value timeout (ACE_OS::gettimeofday () + ACE_Time_Value (10)); f1.set (100); f1.get (value, &timeout); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("1.\n"))); { // Might delete the same data a couple of times. ACE_Future<int> f2 (f1); f1.set (100); f1.get (value, &timeout); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("2.\n"))); { ACE_Future<int> f2 (f1); f1.set (100); f1.get (value, &timeout); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("3.\n"))); { ACE_Future<int> f2 (f1); f1.set (100); f1.get (value, &timeout); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("4.\n"))); { ACE_Future<int> f2 (f1); f1.set (100); f1.get (value, &timeout); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("5.\n"))); { ACE_Future<int> f2 (90); f2.get (value, &timeout); f1.get (value, &timeout); } } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("No it did not crash the program.\n"))); delete andres; delete peter; delete helmut; delete matias; #else ACE_ERROR ((LM_INFO, ACE_TEXT ("threads not supported on this platform\n"))); #endif /* ACE_HAS_THREADS */ ACE_END_TEST; return 0; }
int main (int, ACE_TCHAR *[]) { ACE_START_TEST (ACE_TEXT ("Future_Set_Test")); #if defined (ACE_HAS_THREADS) // @@ Should make these be <auto_ptr>s... Prime_Scheduler *andres, *peter, *helmut, *matias; // Create active objects.. ACE_NEW_RETURN (andres, Prime_Scheduler (ACE_TEXT ("andres")), -1); ACE_ASSERT (andres->open () != -1); ACE_NEW_RETURN (peter, Prime_Scheduler (ACE_TEXT ("peter")), -1); ACE_ASSERT (peter->open () != -1); ACE_NEW_RETURN (helmut, Prime_Scheduler (ACE_TEXT ("helmut")), -1); ACE_ASSERT (helmut->open () != -1); // Matias passes all asynchronous method calls on to Andres... ACE_NEW_RETURN (matias, Prime_Scheduler (ACE_TEXT ("matias"), andres), -1); ACE_ASSERT (matias->open () != -1); ACE_Future<u_long> fresulta; ACE_Future<u_long> fresultb; ACE_Future<u_long> fresultc; ACE_Future<u_long> fresultd; ACE_Future<const ACE_TCHAR *> fname; ACE_Future_Set<u_long> fseta; ACE_Future_Set<u_long> fsetb; ACE_Future_Set<u_long> fsetc; ACE_Future_Set<u_long> fsetd; ACE_Future_Set<const ACE_TCHAR *> fsetname; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) initializing future sets with non-blocking call\n"))); for (int i = 0; i < n_loops; i++) { // Spawn off the methods, which run in a separate thread as // active object invocations. fresulta = andres->work (9013); fresultb = peter->work (9013); fresultc = helmut->work (9013); fresultd = matias->work (9013); fname = andres->name (); fseta.insert (fresulta); fsetb.insert (fresultb); fsetc.insert (fresultc); fsetd.insert (fresultd); fsetname.insert (fname); } // See if the result is available... if (!fseta.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set a is not empty.....\n"))); if (!fsetb.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set b is not empty.....\n"))); if (!fsetc.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set c is not empty.....\n"))); if (!fsetd.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set d is not empty.....\n"))); if (!fsetname.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set name is not empty.....\n"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) non-blocking calls done... now blocking...\n"))); // Save the result of fresulta. u_long resulta = 0; u_long resultb = 0; u_long resultc = 0; u_long resultd = 0; u_int count = 0; while (fseta.next_readable (fresulta)) { fresulta.get (resulta); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) result(%u) a %u\n"), count, (u_int) resulta)); } count = 0; while (fsetb.next_readable (fresultb)) { fresultb.get (resultb); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) result(%u) b %u\n"), count, (u_int) resultb)); } count = 0; while (fsetc.next_readable (fresultc)) { fresultc.get (resultc); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) result(%u) c %u\n"), count, (u_int) resultc)); } count = 0; while (fsetd.next_readable (fresultd)) { fresultd.get (resultd); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) result(%u) d %u\n"), count, (u_int) resultd)); } const ACE_TCHAR *name; count = 0; while (fsetname.next_readable (fname)) { fname.get (name); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) result(%u) name %s\n"), count, name)); } if (fseta.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set a is empty.....\n"))); if (fsetb.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set b is empty.....\n"))); if (fsetc.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set c is empty.....\n"))); if (fsetd.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set d is empty.....\n"))); if (fsetname.is_empty ()) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) wow.. set name is empty.....\n"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) task_count %d\n"), task_count.value () )); // Close things down. andres->end (); peter->end (); helmut->end (); matias->end (); ACE_OS::sleep (2); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) task_count %d\n"), task_count.value () )); ACE_OS::sleep (5); delete andres; delete peter; delete helmut; delete matias; #else ACE_ERROR ((LM_INFO, ACE_TEXT ("threads not supported on this platform\n"))); #endif /* ACE_HAS_THREADS */ ACE_END_TEST; return 0; }
int Method_Request_name::call (void) { return future_result_.set (scheduler_->name_i ()); }