ACE_Reactor보다 ACE_Proactor 개념이 더 어려운걸로 알고 있고 그랬지만..

이상하게 구현하는것은  ACE_Proactor가 훨씬(한 4배) 적용하기 쉽게 느껴진다.

지금까지 Reactor에 목을 맨 나로로는 허망하다 ㅎㅎ

아무튼 최근까지 ACE에 51시간 투자했다.

1차 목표는 8월 31일까지 ACE에 300시간 투자^^
2차 목표는 2011년 5월 31일까지 ACE에 1000시간 투자 목표
최종 목표는 2020년 5월 31일까지 ACE에 1만시간 투자 목표

ACE의 ace가 되는 날까지 보고 해보고 보고 해보고 보고 해보고~~
ACE_Select_Reacot를 ACE_Reactor::instance 에 적용예제
윈도우에서 ACE책 예제(ACE 프로그래머 가이드, C++ NetworkProgramming Volum1, 2)에 나온 소스를 볼때 Select_Reactor로 적용하는것이 작동을 원할하게 할수 있다.


#include "ace/Select_Reactor.h"
#include "ace/Reactor.h"

int ACE_TMAIN( int , ACE_TCHAR * [] )
{
    ACE_Select_Reactor * ps = new ACE_Select_Reactor;

    // 두번째 인자를 true로 하면 Reactor가 삭제될때 첫번째 인자로 넘긴 Reactor를 자동삭제 된다.
    ACE_Reactor * pr = new ACE_Reactor( ps, true );

    // 두번째 인자를 true로 하면 Reactor가 삭제될때 첫번째 인자로 넘긴 Reactor를 자동삭제 된다.
    ACE_Reactor::instance( pr, true );
    ...
    ...

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

    return 0;
}
Task 구현
class LogTest_Task : public ACE_Task<ACE_NULL_SYNCH>
{
	typedef ACE_Task<ACE_NULL_SYNCH>	super;
private:
	ACE_Log_Msg_Callback * m_pLogCallback;

public:
	LogTest_Task( ACE_Log_Msg_Callback * logCallback )	:
		super(),
		m_pLogCallback( logCallback )
	{
	}

	virtual int		svc()
	{
		if( m_pLogCallback )
		{
			ACE_LOG_MSG->set_flags( ACE_Log_Msg::MSG_CALLBACK );
			ACE_LOG_MSG->clr_flags( ACE_Log_Msg::STDERR );
			ACE_LOG_MSG->msg_callback( m_pLogCallback );
		}

		// Log 출력.
		ACE_DEBUG( ( LM_DEBUG,
					ACE_TEXT("DEBUG hello World") ) );
		ACE_ERROR( ( LM_ERROR,
					ACE_TEXT("ERROR hello World") ) );	
		return 0;

	}

};


호출
// Task생성및 Task 실행.
LogTest_Task	logTask( ACE_Log_Msg::instance()->msg_callback() );
logTask.activate();
logTask.wait();
추가된소스
BOOL CACE_MFCApp::InitInstance()
{
        .....

        /////////////////////////////////////////////////////////////////
        // 추가
        WORD                    wVersionRequested;
        WSADATA                 wsaData;
        int             err = 0;

        wVersionRequested = MAKEWORD( 2, 2 );
        if( WSAStartup( wVersionRequested, &wsaData ) != 0 )
                return FALSE;

        ACE::init();
        /////////////////////////////////////////////////////////////////

        CACE_MFCDlg dlg;
        m_pMainWnd = &dlg;
        INT_PTR nResponse = dlg.DoModal();
        if (nResponse == IDOK)
        {
                // TODO: Place code here to handle when the dialog is
                //  dismissed with OK
        }
        else if (nResponse == IDCANCEL)
        {
                // TODO: Place code here to handle when the dialog is
                //  dismissed with Cancel
        }

        /////////////////////////////////////////////////////////////////
        // 추가
        ACE::fini();
        WSACleanup( );
        /////////////////////////////////////////////////////////////////

        // Since the dialog has been closed, return FALSE so that we exit the
        //  application, rather than start the application's message pump.
        return FALSE;
}

Reactor::run_reactor_event_loop 종료후에 다시 Reactor를 썼더니 문제가 일어났다.

문제는 Reactor::notify(handler,mask) 호출이 되지 않는 문제가 발생하여

ACE_Reactor_Notification_Strategy 클래스가 작동을하지 않았다.

그래서 Reactor::reset() 를 호출해봤지만 되지 않았다.

결론은 ACE_Reactor::instance()->reset_reactor_event_loop();

이걸로 해결되었다. ㅎㅎ
메시지 블록 생성 예제

* copy 함수 사용.
ACE_Message_Block * mb=0;
ACE_NEW_REUTRN( mb, ACE_Message_Block( 128 ), -1 );

const char * data = "testData";
mb->copy( data, ACE_OS::strlen( data ) + 1 );

* wr_ptr 사용

ACE_Message_Block * mb=0;
ACE_NEW_REUTRN( mb, ACE_Message_Block( 128 ), -1 );

const char * data = "testData";
ACE_OS::sprintf( mb->wr_ptr(), data );
mb->wr_ptr( ACE_OS::strlen(data)+1 );

+ Recent posts