diff --git a/modules/modperl.cpp b/modules/modperl.cpp index 01ad026f..18686d60 100644 --- a/modules/modperl.cpp +++ b/modules/modperl.cpp @@ -11,9 +11,29 @@ #include class CModPerl; - static CModPerl *g_ModPerl = NULL; +class CModPerlTimer : public CTimer +{ +public: + CModPerlTimer( CModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription ) + : CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {} + virtual ~CModPerlTimer() {} + + void SetFuncName( const string & sFuncName ) + { + m_sFuncName = sFuncName; + } + const string & GetFuncName() { return( m_sFuncName ); } + + virtual void RunJob(); + +protected: + + string m_sFuncName; + +}; + class CModPerl : public CModule { public: @@ -45,13 +65,18 @@ public: return( false ); } - void AddZNCHook( const string & sHookName ) + void AddZNCHook( const string & sHookName ) { m_mssHookNames.insert( sHookName ); } + void DelZNCHook( const string & sHookName ) { - m_mssHookNames.insert( sHookName ); + set< string >::iterator it = m_mssHookNames.find( sHookName ); + if ( it != m_mssHookNames.end() ) + m_mssHookNames.erase( it ); } + int CallBack( const char *pszHookName, ... ); private: + PerlInterpreter *m_pPerl; set< string > m_mssHookNames; @@ -65,44 +90,6 @@ private: CallBack( "Shutdown", NULL ); } - int CallBack( const char *pszHookName, ... ) - { - set< string >::iterator it = m_mssHookNames.find( pszHookName ); - - if ( it == m_mssHookNames.end() ) - return( -1 ); - - va_list ap; - va_start( ap, pszHookName ); - - char *pTmp; - - dSP; - ENTER; - SAVETMPS; - - PUSHMARK( SP ); - while( ( pTmp = va_arg( ap, char * ) ) ) - { - XPUSHs( sv_2mortal( newSVpv( pTmp, strlen( pTmp ) ) ) ); - } - PUTBACK; - - int iCount = call_pv( it->c_str(), G_SCALAR ); - - SPAGAIN; - int iRet = 0; - - if ( iCount == 1 ) - iRet = POPi; - - PUTBACK; - FREETMPS; - LEAVE; - - va_end( ap ); - return( iRet ); - } }; MODULEDEFS( CModPerl ) @@ -115,7 +102,7 @@ XS(XS_AddZNCHook) { dXSARGS; if ( items != 1 ) - Perl_croak(aTHX_ "Usage: AddZNCHook( HookName )"); + Perl_croak( aTHX_ "Usage: AddZNCHook( sFuncName )" ); SP -= items; ax = (SP - PL_stack_base) + 1 ; @@ -128,6 +115,59 @@ XS(XS_AddZNCHook) } } +XS(XS_AddZNCTimer) +{ + dXSARGS; + if ( items != 5 ) + Perl_croak( aTHX_ "Usage: XS_AddZNCTimer( sFuncName, iInterval, iCycles, sLabel, sDesc )" ); + + SP -= items; + ax = (SP - PL_stack_base) + 1 ; + { + if ( g_ModPerl ) + { + string sFuncName = (char *)SvPV(ST(0),PL_na); + u_int iInterval = (u_int)SvIV(ST(1)); + u_int iCycles = (u_int)SvIV(ST(2)); + string sLabel = (char *)SvPV(ST(3),PL_na); + string sDesc = (char *)SvPV(ST(4),PL_na); + + CModPerlTimer *pTimer = new CModPerlTimer( g_ModPerl, iInterval, iCycles, sLabel, sDesc ); + pTimer->SetFuncName( sFuncName ); + g_ModPerl->AddZNCHook( sFuncName ); + g_ModPerl->AddTimer( pTimer ); + } + PUTBACK; + return; + } +} + +XS(XS_KillZNCTimer) +{ + dXSARGS; + if ( items != 1 ) + Perl_croak( aTHX_ "Usage: XS_AddZNCTimer( sLabel )" ); + + SP -= items; + ax = (SP - PL_stack_base) + 1 ; + { + if ( g_ModPerl ) + { + string sLabel = (char *)SvPV(ST(0),PL_na); + + CTimer *pTimer = g_ModPerl->FindTimer( sLabel ); + if ( pTimer ) + { + string sFuncName = ((CModPerlTimer *)pTimer)->GetFuncName(); + g_ModPerl->UnlinkTimer( pTimer ); + if ( !g_ModPerl->FindTimer( sLabel ) ) + g_ModPerl->DelZNCHook( sFuncName ); + } + } + PUTBACK; + return; + } +} /////////// supporting functions from within module @@ -144,10 +184,55 @@ bool CModPerl::OnLoad( const CString & sArgs ) PL_exit_flags |= PERL_EXIT_DESTRUCT_END; newXS( "AddZNCHook", XS_AddZNCHook, (char *)__FILE__ ); + newXS( "AddZNCTimer", XS_AddZNCTimer, (char *)__FILE__ ); + newXS( "KillZNCTimer", XS_KillZNCTimer, (char *)__FILE__ ); ModPerlInit(); return( true ); } -#endif /* HAVE_PERL */ +int CModPerl::CallBack( const char *pszHookName, ... ) +{ + set< string >::iterator it = m_mssHookNames.find( pszHookName ); + if ( it == m_mssHookNames.end() ) + return( -1 ); + + va_list ap; + va_start( ap, pszHookName ); + + char *pTmp; + + dSP; + ENTER; + SAVETMPS; + + PUSHMARK( SP ); + while( ( pTmp = va_arg( ap, char * ) ) ) + { + XPUSHs( sv_2mortal( newSVpv( pTmp, strlen( pTmp ) ) ) ); + } + PUTBACK; + + int iCount = call_pv( it->c_str(), G_SCALAR ); + + SPAGAIN; + int iRet = 0; + + if ( iCount == 1 ) + iRet = POPi; + + PUTBACK; + FREETMPS; + LEAVE; + + va_end( ap ); + return( iRet ); +} + +void CModPerlTimer::RunJob() +{ + ((CModPerl *)m_pModule)->CallBack( m_sFuncName.c_str(), NULL ); +} + +#endif /* HAVE_PERL */