ACE Frequently Made Mistakes

symptom ACE_Task::getq() returns the error resource temporarily unavailable
probable cause Your Task is a subclass of ACE_Task<ACE_NULL_SYNCH> and you are using it in a multithreaded program.
solution Try using ACE_Task<ACE_MT_SYNCH> instead so that the associated Message_Queue is configured for access by multiple threads.

symptom ACE_Task::wait() throws an assert violation
probable cause When you activate()d your Task, you specified THR_DETACHED, which causes wait() to be unable to perform what you want it to.
solution Make sure you specify the flag THR_JOINABLE when activating your ACE_Task object.

symptom Apparent race conditions when spawning threads (or activating Tasks) from within a constructor.
probable cause You are not guaranteed to have a valid this pointer until the constructor has exited. Threads spawned from a constructor are free to run immediately, and may attempt to use an invalid this pointer.
solution Move your Task activations and other thread-spawning activites out of the constructor.

symptom Compiler issues warnings/erros regarding using too few template arguments, such as "'ACE_Svc_Handler' : too few template arguments".
probable cause Instead of using the appropriate macro, you supplied an actual class name as a parameter. This will fail depending upon platform and compiler, due to the way templates are handled.
solution Instead of instantiating a template class like ACE_Svc_Handler<ACE_SOCK_Stream, ACE_NULL_SYNCH>, use the form of ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> which circumvents the platform peculiarities by using the macro. This also applies to some other template classes.

symptom Unable to compare ACE_thread_t variables (such as ACE_Thread::self()) using operator==().
probable cause On some platforms, thread ids are numeric, and on some, they aren't. On some implementations, simple a == b comparisons are legal and sane. Some are not.
solution Use the ACE_OS::thr_equal() function to reliably compare thread ids, regardless of platform.

symptom ACE_Reactor::run_event_loop() does not seem to function correctly for a Reactor created in your application.
probable cause You have not set the ACE_Reactor::instance() to refer to your new reactor. run_event_loop only functions on the reactor currently installed as the global Singleton.
solution Use the ACE_Reactor::instance(ACE_Reactor *, int delete_reactor = 0) static method to install your reactor as the global Singleton before calling run_event_loop().

symptom Infinite recursion when you invoke ACE_Reactor::remove_handler()
probable cause You are invoking remove_handler() from within handle_close() (or a method invoked by handle_close()) but you have not specified the DONT_CALL flag.
solution Be sure to OR in the DONT_CALL flag in this situation.
e.g. --
    int MyHandler::handle_close (ACE_HANDLE handle,
                                 ACE_Reactor_Mask close_mask)
    {
        ...
        my_reactor_->remove_handler( this,
                                    ACE_Event_Handler::READ_MASK |
                                    ACE_Event_Handler::DONT_CALL );
        ...
        return 0;
    }
    

maintained by bob@werken.com