HRESULT CActiveRequestPool::Remove() { HRESULT hr; BOOL signal = FALSE; ENTER_CS(this->syncRoot) ErrorIf(this->requestCount == 0, ERROR_INVALID_OPERATION); this->requestCount--; if (NULL != this->drainHandle && 0 == this->requestCount) { signal = TRUE; } LEAVE_CS(this->syncRoot) if (signal) { SetEvent(this->drainHandle); } return S_OK; Error: return hr; }
HRESULT CActiveRequestPool::Remove(CNodeHttpStoredContext* context) { HRESULT hr; BOOL signal = FALSE; CheckNull(context); ENTER_CS(this->syncRoot) this->requests.remove(context); if (NULL != this->drainHandle && this->requests.empty()) { signal = TRUE; } LEAVE_CS(this->syncRoot) if (signal) { SetEvent(this->drainHandle); } return S_OK; Error: return hr; }
HRESULT CFileWatcher::RemoveWatch(CNodeApplication* application) { ENTER_CS(this->syncRoot) WatchedDirectory* directory = this->directories; WatchedDirectory* previousDirectory = NULL; while (directory) { WatchedFile* file = directory->files; WatchedFile* previousFile = NULL; while (file && file->application != application) { previousFile = file; file = file->next; } if (file) { delete [] file->fileName; if (previousFile) { previousFile->next = file->next; } else { directory->files = file->next; } delete file; if (!directory->files) { delete [] directory->directoryName; CloseHandle(directory->watchHandle); if (previousDirectory) { previousDirectory->next = directory->next; } else { this->directories = directory->next; } delete directory; } break; } previousDirectory = directory; directory = directory->next; } LEAVE_CS(this->syncRoot) return S_OK; }
static void SNP_sendAsyncCmd(_npiFrame_t *pPkt) { // Enter Critical Section. ENTER_CS(); // Send command. SEND_MESSAGE(pPkt); // Exit Critical section EXIT_CS(); }
HRESULT CActiveRequestPool::Add(CNodeHttpStoredContext* context) { HRESULT hr; CheckNull(context); ENTER_CS(this->syncRoot) ErrorIf(this->requests.size() >= CModuleConfiguration::GetMaxConcurrentRequestsPerProcess(context->GetHttpContext()), ERROR_NOT_ENOUGH_QUOTA); this->requests.push_back(context); LEAVE_CS(this->syncRoot) return S_OK; Error: return hr; }
HRESULT CPendingRequestQueue::Push(CNodeHttpStoredContext* context) { HRESULT hr; CheckNull(context); ENTER_CS(this->syncRoot) ErrorIf(this->requests.size() >= CModuleConfiguration::GetMaxPendingRequestsPerApplication(context->GetHttpContext()), ERROR_NOT_ENOUGH_QUOTA); this->requests.push(context); LEAVE_CS(this->syncRoot) return S_OK; Error: return hr; }
HRESULT CNodeApplicationManager::Dispatch(IHttpContext* context, IHttpEventProvider* pProvider, CNodeHttpStoredContext** ctx) { HRESULT hr; CNodeApplication* application; NodeDebugCommand debugCommand; CheckNull(ctx); *ctx = NULL; CheckError(CNodeDebugger::GetDebugCommand(context, this->GetEventProvider(), &debugCommand)); if (ND_KILL == debugCommand) { ENTER_CS(this->syncRoot) CheckError(this->EnsureDebuggedApplicationKilled(context, ctx)); LEAVE_CS(this->syncRoot) }
static void SNP_sendSynchronousCmd(_npiFrame_t *pReq, uint8_t opcode, snp_msg_t *pRsp, uint16_t *rspLen) { // Enter Critical Section. ENTER_CS(); npiRetMsg.pMsg = pRsp; // Send command. SEND_MESSAGE(pReq); // Wait for a response from the NP. SNP_waitForResponse(); // Update Length after response is received if (rspLen) { *rspLen = npiRetMsg.len; } // Exit Critical Section EXIT_CS(); }
HRESULT CFileWatcher::WatchFiles(PCWSTR mainFileName, PCWSTR watchedFiles, FileModifiedCallback callback, CNodeApplicationManager* manager, CNodeApplication* application) { HRESULT hr; WCHAR fileOnly[_MAX_FNAME]; WCHAR ext[_MAX_EXT]; WCHAR* directoryName = NULL; DWORD fileNameLength; DWORD fileNameOnlyLength; DWORD directoryLength; BOOL unc; BOOL wildcard; PWSTR startSubdirectory; PWSTR startFile; PWSTR endFile; WatchedDirectory* directory; WatchedFile* file; CheckNull(mainFileName); CheckNull(watchedFiles); // create and normalize a copy of directory name, determine if it is UNC share fileNameLength = wcslen(mainFileName); ErrorIf(0 != _wsplitpath_s(mainFileName, NULL, 0, NULL, 0, fileOnly, _MAX_FNAME, ext, _MAX_EXT), ERROR_INVALID_PARAMETER); fileNameOnlyLength = wcslen(fileOnly) + wcslen(ext); directoryLength = fileNameLength - fileNameOnlyLength; ErrorIf(NULL == (directoryName = new WCHAR[directoryLength + 8]), ERROR_NOT_ENOUGH_MEMORY); // pessimistic length after normalization with prefix \\?\UNC\ if (fileNameLength > 8 && 0 == memcmp(mainFileName, L"\\\\?\\UNC\\", 8 * sizeof WCHAR)) { // normalized UNC path unc = TRUE; memcpy(directoryName, mainFileName, directoryLength * sizeof WCHAR); directoryName[directoryLength] = L'\0'; } else if (fileNameLength > 4 && 0 == memcmp(mainFileName, L"\\\\?\\", 4 * sizeof WCHAR)) { // normalized local file unc = FALSE; memcpy(directoryName, mainFileName, directoryLength * sizeof WCHAR); directoryName[directoryLength] = L'\0'; } else if (fileNameLength > 2 && 0 == memcmp(mainFileName, L"\\\\", 2 * sizeof(WCHAR))) { // not normalized UNC path unc = TRUE; wcscpy(directoryName, L"\\\\?\\UNC\\"); memcpy(directoryName + 8, mainFileName + 2, (directoryLength - 2) * sizeof WCHAR); directoryName[8 + directoryLength - 2] = L'\0'; } else { // not normalized local file unc = FALSE; wcscpy(directoryName, L"\\\\?\\"); memcpy(directoryName + 4, mainFileName, directoryLength * sizeof WCHAR); directoryName[4 + directoryLength] = L'\0'; } directoryLength = wcslen(directoryName); ENTER_CS(this->syncRoot) // parse watchedFiles and create a file listener for each of the files startFile = (PWSTR)watchedFiles; do { endFile = startSubdirectory = startFile; wildcard = FALSE; while (*endFile && *endFile != L';') { wildcard |= *endFile == L'*' || *endFile == L'?'; if (*endFile == L'\\') { startFile = endFile + 1; } endFile++; } if (startFile != endFile) { hr = this->WatchFile(directoryName, directoryLength, unc, startSubdirectory, startFile, endFile, wildcard); // ignore files and directories that do not exist instead of failing if (S_OK != hr && ERROR_FILE_NOT_FOUND != hr) { // still under lock remove file watch entries that were just created, then do regular cleanup this->RemoveWatch(NULL); CheckError(hr); } } startFile = endFile + 1; } while(*endFile); // update temporary entries with application and callback pointers directory = this->directories; while (NULL != directory) { file = directory->files; while (NULL != file) { if (NULL == file->application) { file->application = application; file->manager = manager; file->callback = callback; } file = file->next; } directory = directory->next; } LEAVE_CS(this->syncRoot) delete [] directoryName; return S_OK; Error: if (NULL != directoryName) { delete [] directoryName; directoryName = NULL; } return hr; }
unsigned int CFileWatcher::Worker(void* arg) { CFileWatcher* watcher = (CFileWatcher*)arg; DWORD error; DWORD bytes; ULONG_PTR key; LPOVERLAPPED overlapped; while (TRUE) { error = S_OK; if (!GetQueuedCompletionStatus( watcher->completionPort, &bytes, &key, &overlapped, watcher->uncFileSharePollingInterval)) { error = GetLastError(); } if (-1L == key) // terminate thread { break; } else if (S_OK == error) // a change in registered directory detected (local file system) { WatchedDirectory* directory = (WatchedDirectory*)key; ENTER_CS(watcher->syncRoot) // make sure the directory is still watched WatchedDirectory* current = watcher->directories; while (current && current != directory) current = current->next; if (current) { watcher->ScanDirectory(current, FALSE); // make sure the directory is still watched - it could have been removed by a recursive call to RemoveWatch current = watcher->directories; while (current && current != directory) current = current->next; if (current) { RtlZeroMemory(¤t->overlapped, sizeof current->overlapped); ReadDirectoryChangesW( current->watchHandle, ¤t->info, sizeof directory->info, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, NULL, ¤t->overlapped, NULL); } } LEAVE_CS(watcher->syncRoot) } else // timeout - scan all registered UNC files for changes {
HRESULT CFileWatcher::RemoveWatch(CNodeApplication* application) { ENTER_CS(this->syncRoot) WatchedDirectory* directory = this->directories; WatchedDirectory* previousDirectory = NULL; while (directory) { WatchedFile* file = directory->files; WatchedFile* previousFile = NULL; while (file) { if (file->application == application) { WatchedFile* tmpFile = file; delete [] file->fileName; if (previousFile) { previousFile->next = file->next; file = file->next; if (!file) { previousDirectory = directory; directory = directory->next; } } else { directory->files = file->next; file = file->next; if (!directory->files) { delete [] directory->directoryName; if(directory->watchHandle != NULL) { CloseHandle(directory->watchHandle); directory->watchHandle = NULL; } if (previousDirectory) { previousDirectory->next = directory->next; } else { this->directories = directory->next; } WatchedDirectory* tmpDirectory = directory; directory = directory->next; delete tmpDirectory; } } delete tmpFile; } else { previousFile = file; file = file->next; if (!file) { previousDirectory = directory; directory = directory->next; } } } } LEAVE_CS(this->syncRoot) return S_OK; }