Skip to content

Commit

Permalink
Merge pull request #365 from Azure/iisnode-dev
Browse files Browse the repository at this point in the history
v0.2.15
  • Loading branch information
rramachand21 committed Aug 4, 2014
2 parents 57401b0 + 66d9afd commit ee6c9bf
Show file tree
Hide file tree
Showing 19 changed files with 1,414 additions and 828 deletions.
4 changes: 2 additions & 2 deletions src/iisnode/chttpprotocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ HRESULT CHttpProtocol::ParseResponseStatusLine(CNodeHttpStoredContext* context)

if (ERROR_MORE_DATA != hr)
{
context->GetNodeApplication()->GetApplicationManager()->GetEventProvider()->Log(
context->GetNodeApplication()->GetApplicationManager()->GetEventProvider()->Log( context->GetHttpContext(),
L"iisnode failed to parse response status line", WINEVENT_LEVEL_ERROR, context->GetActivityId());
}

Expand Down Expand Up @@ -470,7 +470,7 @@ HRESULT CHttpProtocol::ParseChunkHeader(CNodeHttpStoredContext* context)

if (ERROR_MORE_DATA != hr)
{
context->GetNodeApplication()->GetApplicationManager()->GetEventProvider()->Log(
context->GetNodeApplication()->GetApplicationManager()->GetEventProvider()->Log( context->GetHttpContext(),
L"iisnode failed to parse response body chunk header", WINEVENT_LEVEL_ERROR, context->GetActivityId());

return hr;
Expand Down
4 changes: 2 additions & 2 deletions src/iisnode/cnodeapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ HRESULT CNodeApplication::Initialize(PCWSTR scriptName, IHttpContext* context)
this->GetApplicationManager(),
this));

this->GetApplicationManager()->GetEventProvider()->Log(L"iisnode initialized a new node.js application", WINEVENT_LEVEL_INFO);
this->GetApplicationManager()->GetEventProvider()->Log(context, L"iisnode initialized a new node.js application", WINEVENT_LEVEL_INFO);

return S_OK;
Error:

this->GetApplicationManager()->GetEventProvider()->Log(L"iisnode failed to initialize a new node.js application", WINEVENT_LEVEL_ERROR);
this->GetApplicationManager()->GetEventProvider()->Log(context, L"iisnode failed to initialize a new node.js application", WINEVENT_LEVEL_ERROR);

this->Cleanup();

Expand Down
187 changes: 132 additions & 55 deletions src/iisnode/cnodeapplicationmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CNodeApplicationManager::CNodeApplicationManager(IHttpServer* server, HTTP_MODUL
: server(server), moduleId(moduleId), applications(NULL), asyncManager(NULL), jobObject(NULL),
breakAwayFromJobObject(FALSE), fileWatcher(NULL), initialized(FALSE), eventProvider(NULL),
currentDebugPort(0), inspector(NULL), totalRequests(0), controlSignalHandlerThread(NULL),
signalPipe(NULL), signalPipeName(NULL), pPipeSecAttr(NULL)
signalPipe(NULL), signalPipeName(NULL), pPipeSecAttr(NULL), _fSignalPipeInitialized( FALSE )
{
InitializeSRWLock(&this->srwlock);
}
Expand Down Expand Up @@ -90,13 +90,95 @@ CNodeApplicationManager::GetPipeSecurityAttributes(
return this->pPipeSecAttr;
}

HRESULT CNodeApplicationManager::InitializeControlPipe()
{
HRESULT hr = S_OK;
UUID uuid;
RPC_WSTR suuid = NULL;

if( _fSignalPipeInitialized )
{
return hr;
}

//
// generate unique pipe name
//

ErrorIf(RPC_S_OK != UuidCreate(&uuid), ERROR_CAN_NOT_COMPLETE);
ErrorIf(RPC_S_OK != UuidToStringW(&uuid, &suuid), ERROR_NOT_ENOUGH_MEMORY);
ErrorIf((this->signalPipeName = new WCHAR[1024]) == NULL, ERROR_NOT_ENOUGH_MEMORY);
wcscpy(this->signalPipeName, L"\\\\.\\pipe\\");
wcscpy(this->signalPipeName + 9, (WCHAR*)suuid);
RpcStringFreeW(&suuid);
suuid = NULL;

this->signalPipe = CreateNamedPipeW( this->signalPipeName,
PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE | PIPE_WAIT,
1,
MAX_BUFFER_SIZE,
MAX_BUFFER_SIZE,
0,
GetPipeSecurityAttributes() );

ErrorIf( this->signalPipe == INVALID_HANDLE_VALUE,
HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE) );

//
// start pipe reader thread.
//

this->controlSignalHandlerThread = (HANDLE) _beginthreadex( NULL,
0,
CNodeApplicationManager::ControlSignalHandler,
this,
0,
NULL);

ErrorIf((HANDLE)-1L == this->controlSignalHandlerThread, ERROR_NOT_ENOUGH_MEMORY);

this->GetEventProvider()->Log(L"iisnode initialized control pipe", WINEVENT_LEVEL_INFO);

_fSignalPipeInitialized = TRUE;

Error:

if(suuid != NULL)
{
RpcStringFreeW(&suuid);
suuid = NULL;
}

if( FAILED( hr ) )
{
if(NULL != this->controlSignalHandlerThread)
{
CloseHandle(this->controlSignalHandlerThread);
this->controlSignalHandlerThread = NULL;
}

if(NULL != this->signalPipe)
{
CloseHandle(this->signalPipe);
this->signalPipe = NULL;
}

if(NULL != this->signalPipeName)
{
delete[] this->signalPipeName;
this->signalPipeName = NULL;
}
}

return hr;
}

HRESULT CNodeApplicationManager::InitializeCore(IHttpContext* context)
{
HRESULT hr;
BOOL isInJob, createJob;
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo;
UUID uuid;
RPC_WSTR suuid = NULL;

ErrorIf(NULL == (this->eventProvider = new CNodeEventProvider()), ERROR_NOT_ENOUGH_MEMORY);
CheckError(this->eventProvider->Initialize());
Expand Down Expand Up @@ -150,62 +232,19 @@ HRESULT CNodeApplicationManager::InitializeCore(IHttpContext* context)
HRESULT_FROM_WIN32(GetLastError()));
}

if(CModuleConfiguration::GetRecycleSignalEnabled(context))
if(CModuleConfiguration::GetRecycleSignalEnabled(context) && !_fSignalPipeInitialized)
{
//
// generate unique pipe name
//

ErrorIf(RPC_S_OK != UuidCreate(&uuid), ERROR_CAN_NOT_COMPLETE);
ErrorIf(RPC_S_OK != UuidToStringW(&uuid, &suuid), ERROR_NOT_ENOUGH_MEMORY);
ErrorIf((this->signalPipeName = new WCHAR[1024]) == NULL, ERROR_NOT_ENOUGH_MEMORY);
wcscpy(this->signalPipeName, L"\\\\.\\pipe\\");
wcscpy(this->signalPipeName + 9, (WCHAR*)suuid);
RpcStringFreeW(&suuid);
suuid = NULL;

this->signalPipe = CreateNamedPipeW( this->signalPipeName,
PIPE_ACCESS_INBOUND,
PIPE_TYPE_MESSAGE | PIPE_WAIT,
1,
MAX_BUFFER_SIZE,
MAX_BUFFER_SIZE,
0,
GetPipeSecurityAttributes() );

ErrorIf( this->signalPipe == INVALID_HANDLE_VALUE,
HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE) );

//
// start pipe reader thread.
//

this->controlSignalHandlerThread = (HANDLE) _beginthreadex( NULL,
0,
CNodeApplicationManager::ControlSignalHandler,
this,
0,
NULL);

ErrorIf((HANDLE)-1L == this->controlSignalHandlerThread, ERROR_NOT_ENOUGH_MEMORY);

this->GetEventProvider()->Log(L"iisnode initialized control pipe", WINEVENT_LEVEL_INFO);
CheckError(InitializeControlPipe());
}

this->initialized = TRUE;

this->GetEventProvider()->Log(L"iisnode initialized the application manager", WINEVENT_LEVEL_INFO);
this->GetEventProvider()->Log(context, L"iisnode initialized the application manager", WINEVENT_LEVEL_INFO);

return S_OK;
Error:

this->GetEventProvider()->Log(L"iisnode failed to initialize the application manager", WINEVENT_LEVEL_ERROR);

if(suuid != NULL)
{
RpcStringFreeW(&suuid);
suuid = NULL;
}
this->GetEventProvider()->Log(context, L"iisnode failed to initialize the application manager", WINEVENT_LEVEL_ERROR);

if (NULL != this->asyncManager)
{
Expand All @@ -230,6 +269,8 @@ HRESULT CNodeApplicationManager::InitializeCore(IHttpContext* context)

CNodeApplicationManager::~CNodeApplicationManager()
{
HANDLE hPipe = NULL;

while (NULL != this->applications)
{
delete this->applications->nodeApplication;
Expand All @@ -238,6 +279,30 @@ CNodeApplicationManager::~CNodeApplicationManager()
delete current;
}

if( _fSignalPipeInitialized )
{
//
// try to connect to the pipe to unblock the thread
// waiting on ConnectNamedPipe
// We dont need to check any errors on whether the connect
// succeeded because we dont care.
//

hPipe = CreateFileW( this->GetSignalPipeName(),
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL );

if(hPipe != NULL)
{
CloseHandle(hPipe);
hPipe = NULL;
}
}

if(NULL != this->controlSignalHandlerThread)
{
CloseHandle(this->controlSignalHandlerThread);
Expand Down Expand Up @@ -304,7 +369,7 @@ CAsyncManager* CNodeApplicationManager::GetAsyncManager()

HRESULT CNodeApplicationManager::Dispatch(IHttpContext* context, IHttpEventProvider* pProvider, CNodeHttpStoredContext** ctx)
{
HRESULT hr;
HRESULT hr = S_OK;
CNodeApplication* application;
NodeDebugCommand debugCommand;

Expand All @@ -319,6 +384,18 @@ HRESULT CNodeApplicationManager::Dispatch(IHttpContext* context, IHttpEventProvi
{
default:

if(CModuleConfiguration::GetRecycleSignalEnabled(context) && !_fSignalPipeInitialized)
{
ENTER_SRW_EXCLUSIVE(this->srwlock)

if(CModuleConfiguration::GetRecycleSignalEnabled(context) && !_fSignalPipeInitialized)
{
CheckError(InitializeControlPipe());
}

LEAVE_SRW_EXCLUSIVE(this->srwlock)
}

ENTER_SRW_SHARED(this->srwlock)

CheckError(this->GetOrCreateNodeApplication(context, debugCommand, FALSE, &application));
Expand Down Expand Up @@ -554,7 +631,7 @@ HRESULT CNodeApplicationManager::GetOrCreateNodeApplicationCore(PCWSTR physicalP
}
else
{
this->GetEventProvider()->Log(L"iisnode found an existing node.js application to dispatch the http request to", WINEVENT_LEVEL_VERBOSE);
this->GetEventProvider()->Log(context, L"iisnode found an existing node.js application to dispatch the http request to", WINEVENT_LEVEL_VERBOSE);
}

return S_OK;
Expand All @@ -569,7 +646,7 @@ HRESULT CNodeApplicationManager::GetOrCreateNodeApplicationCore(PCWSTR physicalP
delete applicationEntry;
}

this->GetEventProvider()->Log(L"iisnode failed to create a new node.js application", WINEVENT_LEVEL_ERROR);
this->GetEventProvider()->Log(context, L"iisnode failed to create a new node.js application", WINEVENT_LEVEL_ERROR);

return hr;
}
Expand Down Expand Up @@ -860,7 +937,7 @@ HRESULT CNodeApplicationManager::GetOrCreateDebuggedNodeApplicationCore(PCWSTR p
}
else
{
this->GetEventProvider()->Log(L"iisnode found an existing node.js debugger to dispatch the http request to", WINEVENT_LEVEL_VERBOSE);
this->GetEventProvider()->Log(context, L"iisnode found an existing node.js debugger to dispatch the http request to", WINEVENT_LEVEL_VERBOSE);
}

return S_OK;
Expand All @@ -884,7 +961,7 @@ HRESULT CNodeApplicationManager::GetOrCreateDebuggedNodeApplicationCore(PCWSTR p
delete debuggerEntry;
}

this->GetEventProvider()->Log(L"iisnode failed to create a new node.js application to debug or the debugger for that application", WINEVENT_LEVEL_ERROR);
this->GetEventProvider()->Log(context, L"iisnode failed to create a new node.js application to debug or the debugger for that application", WINEVENT_LEVEL_ERROR);

return hr;
}
Expand Down
3 changes: 2 additions & 1 deletion src/iisnode/cnodeapplicationmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class CNodeApplicationManager
HMODULE inspector;
LONG totalRequests;

BOOL _fSignalPipeInitialized;
HANDLE signalPipe;
HANDLE controlSignalHandlerThread;
LPWSTR signalPipeName;
Expand All @@ -65,7 +66,7 @@ class CNodeApplicationManager
HRESULT FindNextDebugPort(IHttpContext* context, DWORD* port);
HRESULT EnsureDebugeeReady(IHttpContext* context, DWORD debugPort);
HRESULT InitializeCore(IHttpContext* context);

HRESULT InitializeControlPipe();
static unsigned int WINAPI ControlSignalHandler(void* arg);

public:
Expand Down
Loading

0 comments on commit ee6c9bf

Please sign in to comment.