[Ace-users] a thread blocked by the other one

zhangwei zhangwei.chs at gmail.com
Wed Jul 11 03:19:33 CDT 2007


Hi,
   I have a class that derive from ACE_Task_Base.
   In virtual function "svc",I defined a object by template
  ACE_Acceptor,and then call the "open" method to accept
  a connection.
   In main fuction, I defined two object by "ConntionHandler",
  then call "activate" method in twice to create two threads.
  Most if time only one thread can execute  , the other seems
  not create. However, they are both run once or twice.
  I have added the recursive mutex for send and recv.
  PRF below.

Thanks
zhangwei

--------------- PRF -------------------------------------------

To: ace-b... at cs.wustl.edu
Subject: ACE_Task_Base class, threads block


    ACE VERSION: 5.5


    HOST MACHINE and OPERATING SYSTEM:
        i386-redhat-linux


    TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
    COMPILER NAME AND VERSION (AND PATCHLEVEL):
        g++  version 3.2.3


    CONTENTS OF $ACE_ROOT/ace/config.h [if you use a link to a
platform-
    specific file, simply state which one]:
        autoconf built version (or config-linux.h)


    CONTENTS OF $ACE_ROOT/include/makeinclude/platform_macros.GNU
(unless
    this isn't used in this case, e.g., with Microsoft Visual C++):
        not applicable


    CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/
default.features
    (used by MPC when you generate your own makefiles):
        not applicable


    AREA/CLASS/EXAMPLE AFFECTED:
        ACE_Stream, ACE_Task_Base, template ACE_Acceptor


    DOES THE PROBLEM AFFECT:
        COMPILATION?
        LINKING?
            On Unix systems, did you run make realclean first?
        EXECUTION?
        OTHER (please specify)?
        not applicable


    SYNOPSIS:
        General questions about thread block of ACE_Task_Base


    DESCRIPTION:
      See above.


    REPEAT BY:


    SAMPLE FIX/WORKAROUND:
    code in main():
        ConntionHandler channel_handler(ARBITER_CHANNEL);
        ConntionHandler conn_handler(CELL_CONN);

        int channel_result = channel_handler.activate(
                                THR_NEW_LWP | THR_JOINABLE,
                                1,1,
                                ACE_THR_PRI_OTHER_MAX);
        ACE_ASSERT(channel_result == 0);


        ACE_TRY_CHECK

        int create_result = conn_handler.activate(
                                THR_NEW_LWP | THR_JOINABLE,
                                1,1,
                                ACE_THR_PRI_OTHER_DEF);
        ACE_ASSERT(create_result == 0);

        ACE_TRY_CHECK


        channel_handler.wait();
        conn_handler.wait();
************************************************************
   class ConntionHandler : public ACE_Task_Base
        {
            public:
                ConntionHandler(short mode,int argc,ACE_TCHAR **argv);

                ConntionHandler(short mode);

                virtual ~ConntionHandler();

                virtual int svc(void);

            private:
                short mode_;
                int argc_;
                ACE_TCHAR **argv_;
                static int order_;
                ACE_Thread_Mutex mutex_;
                ACE_Condition<ACE_Thread_Mutex> cond_;
         };
************************************************************
typedef ACE_Acceptor<ClientService, ACE_SOCK_ACCEPTOR>ClientAcceptor;

int ConntionHandler::order_ = 0;

int ConntionHandler::svc()
{
    gcfi.getConfig("NE_Deal.xml");

#ifdef DEBUG

    ACE_thread_t tid = this->thr_mgr ()->thr_self ();

    printf("New Thread run, id = %d\n",(int)tid);
#endif

    if (CELL_CONN == mode_)
    {
        mutex_.acquire();

        while( order_ != 1)
                cond_.wait();

        mutex_.release();

  //deal timer
        MyTimerHandler * timer = new MyTimerHandler ();
        ACE_Time_Value initialDelay (INITIALDELAY_TIME);
        ACE_Time_Value interval (INTERVAL_TIME);
        ACE_Reactor::instance()->schedule_timer (timer,
                                           0,
                                           initialDelay,
                                           interval);
        //deal signal
        LoopStopper *handleSigint = new LoopStopper (SIGINT);

        ACE_INET_Addr port_to_listen (SEND_PORT,ACE_LOCALHOST);

        ClientAcceptor acceptor;

        if (acceptor.open (port_to_listen) == -1)
            return 1;

        ACE_Reactor::instance ()->run_reactor_event_loop ();

    }
    else if (ARBITER_CHANNEL == mode_)
    {
        gne.init (argc_, argv_ ACE_ENV_ARG_PARAMETER);
        ACE_CHECK

        gne.run (ACE_ENV_SINGLE_ARG_PARAMETER);
        ACE_CHECK

        mutex_.acquire();

        order_ = 1;

        cond_.signal();

        mutex_.release();

    }

    return 0;
}



More information about the Ace-users mailing list