11#include " precomp.h"
22
3+ volatile DWORD CNodeApplication::dwInternalAppId = 0 ;
4+
35CNodeApplication::CNodeApplication (CNodeApplicationManager* applicationManager, BOOL isDebugger, NodeDebugCommand debugCommand, DWORD debugPort)
46 : applicationManager(applicationManager), scriptName(NULL ), processManager(NULL ),
57 isDebugger(isDebugger), peerApplication(NULL ), debugCommand(debugCommand),
6- debugPort(debugPort), needsRecycling(FALSE ), configPath(NULL )
8+ debugPort(debugPort), needsRecycling(FALSE ), configPath(NULL ), pIdleTimer(NULL ),
9+ fIdleCallbackInProgress(FALSE ), fRequestsProcessedInLastIdleTimeoutPeriod(FALSE ),
10+ fEmptyWorkingSetAtStart(FALSE ), dwIdlePageOutTimePeriod(0 )
11+ {
12+ }
13+
14+ VOID
15+ CALLBACK
16+ CNodeApplication::IdleTimerCallback (
17+ IN PTP_CALLBACK_INSTANCE Instance,
18+ IN PVOID Context,
19+ IN PTP_TIMER Timer
20+ )
721{
22+ CNodeApplication* pApplication = (CNodeApplication*) Context;
23+ if (pApplication != NULL )
24+ {
25+ if (!pApplication->fIdleCallbackInProgress )
26+ {
27+ pApplication->fIdleCallbackInProgress = TRUE ;
28+
29+ if (!pApplication->fRequestsProcessedInLastIdleTimeoutPeriod || !pApplication->fEmptyWorkingSetAtStart )
30+ {
31+ pApplication->fEmptyWorkingSetAtStart = TRUE ;
32+ pApplication->EmptyWorkingSet ();
33+ if ( pApplication->fEmptyW3WPWorkingSet )
34+ {
35+ SetProcessWorkingSetSize (GetCurrentProcess (), -1 , -1 );
36+ }
37+ }
38+
39+ pApplication->fRequestsProcessedInLastIdleTimeoutPeriod = FALSE ;
40+
41+ if (pApplication->pIdleTimer != NULL )
42+ {
43+ pApplication->pIdleTimer ->SetTimer (pApplication->dwIdlePageOutTimePeriod , 0 );
44+ }
45+ }
46+ pApplication->fIdleCallbackInProgress = FALSE ;
47+ }
848}
949
1050CNodeApplication::~CNodeApplication ()
@@ -14,6 +54,13 @@ CNodeApplication::~CNodeApplication()
1454
1555void CNodeApplication::Cleanup ()
1656{
57+ if (this ->pIdleTimer != NULL )
58+ {
59+ this ->pIdleTimer ->CancelTimer ();
60+ delete this ->pIdleTimer ;
61+ this ->pIdleTimer = NULL ;
62+ }
63+
1764 this ->GetApplicationManager ()->GetFileWatcher ()->RemoveWatch (this );
1865
1966 if (NULL != this ->scriptName )
@@ -41,6 +88,26 @@ HRESULT CNodeApplication::Initialize(PCWSTR scriptName, IHttpContext* context)
4188
4289 CheckNull (scriptName);
4390
91+ if (CModuleConfiguration::GetIdlePageOutTimePeriod (context) > 0 )
92+ {
93+ dwIdlePageOutTimePeriod = CModuleConfiguration::GetIdlePageOutTimePeriod (context);
94+ if (dwInternalAppId == 0 )
95+ {
96+ dwInternalAppId ++;
97+ this ->fEmptyW3WPWorkingSet = TRUE ;
98+ }
99+ if (pIdleTimer == NULL )
100+ {
101+ pIdleTimer = new STTIMER;
102+ ErrorIf (pIdleTimer == NULL , E_OUTOFMEMORY);
103+ CheckError (pIdleTimer->InitializeTimer ( CNodeApplication::IdleTimerCallback, this , 10000 , 0 ));
104+ }
105+ else
106+ {
107+ pIdleTimer->SetTimer (10000 , 0 );
108+ }
109+ }
110+
44111 DWORD len = wcslen (scriptName) + 1 ;
45112 ErrorIf (NULL == (this ->scriptName = new WCHAR[len]), ERROR_NOT_ENOUGH_MEMORY);
46113 wcscpy (this ->scriptName , scriptName);
@@ -74,6 +141,11 @@ PCWSTR CNodeApplication::GetConfigPath()
74141 return this ->configPath ;
75142}
76143
144+ HRESULT CNodeApplication::EmptyWorkingSet ()
145+ {
146+ return this ->processManager ->EmptyWorkingSet ();
147+ }
148+
77149HRESULT CNodeApplication::SetConfigPath (IHttpContext * context)
78150{
79151 HRESULT hr = S_OK;
@@ -109,6 +181,8 @@ HRESULT CNodeApplication::Dispatch(IHttpContext* context, IHttpEventProvider* pP
109181 CheckNull (context);
110182 CheckNull (pProvider);
111183
184+ fRequestsProcessedInLastIdleTimeoutPeriod = TRUE ;
185+
112186 ErrorIf (NULL == (*ctx = new CNodeHttpStoredContext (this , this ->GetApplicationManager ()->GetEventProvider (), context)), ERROR_NOT_ENOUGH_MEMORY);
113187 IHttpModuleContextContainer* moduleContextContainer = context->GetModuleContextContainer ();
114188 moduleContextContainer->SetModuleContext (*ctx, this ->GetApplicationManager ()->GetModuleId ());
0 commit comments