Skip to content

Commit

Permalink
General functionality working, whole lot of cleanup now
Browse files Browse the repository at this point in the history
  • Loading branch information
jkotalik committed Feb 4, 2021
1 parent 427cb26 commit a45a3dd
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,26 @@
#include "debugutil.h"
#include "AppOfflineTrackingApplication.h"
#include "exceptions.h"
#include <EventLog.h>

FILE_WATCHER::FILE_WATCHER() :
m_hCompletionPort(NULL),
m_hChangeNotificationThread(NULL),
m_fThreadExit(FALSE),
_fTrackDllChanges(FALSE)
_fTrackDllChanges(FALSE),
m_copied(false)
{
m_pShutdownEvent = CreateEvent(
nullptr, // default security attributes
TRUE, // manual reset event
FALSE, // not set
nullptr); // name
}

FILE_WATCHER::~FILE_WATCHER()
{
StopMonitor();
WaitForMonitor(20);
WaitForMonitor(20000);
}

void FILE_WATCHER::WaitForMonitor(DWORD dwRetryCounter)
Expand Down Expand Up @@ -60,7 +67,7 @@ FILE_WATCHER::Create(
_In_ PCWSTR pszFileNameToMonitor,
_In_ bool fTrackDllChanges,
_In_ std::wstring shadowCopyPath,
_In_ AppOfflineTrackingApplication *pApplication
_In_ AppOfflineTrackingApplication* pApplication
)
{
_shadowCopyPath = shadowCopyPath;
Expand Down Expand Up @@ -138,10 +145,10 @@ Win32 error
--*/
{
FILE_WATCHER * pFileMonitor;
FILE_WATCHER* pFileMonitor;
BOOL fSuccess = FALSE;
DWORD cbCompletion = 0;
OVERLAPPED * pOverlapped = NULL;
OVERLAPPED* pOverlapped = NULL;
DWORD dwErrorStatus;
ULONG_PTR completionKey;

Expand Down Expand Up @@ -185,7 +192,15 @@ Win32 error

pFileMonitor->m_fThreadExit = TRUE;

// TODO check instead for if a dll was changed here
if (pFileMonitor->_fTrackDllChanges)
{
pFileMonitor->m_Timer.CancelTimer();
FILE_WATCHER::CopyAndShutdown(pFileMonitor);
}

LOG_INFO(L"Stopping file watcher thread");

ExitThread(0);
}

Expand Down Expand Up @@ -265,6 +280,7 @@ HRESULT
if (_fTrackDllChanges && notificationPath.extension().compare(L".dll") == 0)
{
fFileChanged = TRUE;
_fDllHadChanged = true;
fDllChanged = TRUE;
}

Expand All @@ -288,21 +304,72 @@ HRESULT
{
// Reference application before
_pApplication->ReferenceApplication();
if (fDllChanged)
if (fDllChanged || _fTrackDllChanges)
{
// wait for all file changes to complete
PostQueuedCompletionStatus(m_hCompletionPort, 0, FILE_WATCHER_SHUTDOWN_KEY, NULL);
WaitForMonitor(100); // 5 seconds here.

// Copy contents before shutdown
RETURN_IF_FAILED(Environment::CopyToDirectory(_shadowCopyPath, _strDirectoryName.QueryStr(), false));
// Call shutdown later.
m_Timer.CancelTimer();
m_Timer.InitializeTimer(FILE_WATCHER::TimerCallback, this, 5000, 3000);
}
else
{
RETURN_LAST_ERROR_IF(!QueueUserWorkItem(RunNotificationCallback, _pApplication.get(), WT_EXECUTEDEFAULT));
}
RETURN_LAST_ERROR_IF(!QueueUserWorkItem(RunNotificationCallback, _pApplication.get(), WT_EXECUTEDEFAULT));
}

return S_OK;
}


VOID
CALLBACK
FILE_WATCHER::TimerCallback(
_In_ PTP_CALLBACK_INSTANCE Instance,
_In_ PVOID Context,
_In_ PTP_TIMER Timer
)
{
// Need to lock here.
Instance;
Timer;
CopyAndShutdown((FILE_WATCHER*)Context);
}

DWORD WINAPI FILE_WATCHER::CopyAndShutdown(LPVOID arg)
{
EventLog::Error(
1,
L"Callback");
auto directoryName = 0;
// wrong path.
auto watcher = (FILE_WATCHER*)arg;
SRWExclusiveLock lock(watcher->m_copyLock);

if (watcher->m_copied)
{
return 0;
}

watcher->m_copied = true;

auto dir = std::filesystem::path(watcher->_shadowCopyPath);
auto parent = dir.parent_path();
directoryName = std::stoi(dir.filename().string());

directoryName++;
auto dirNameStr = std::to_wstring(directoryName);
auto destination = parent / dirNameStr.c_str();

// Copy contents before shutdown
Environment::CopyToDirectory(destination, watcher->_strDirectoryName.QueryStr(), false);

watcher->_pApplication->ReferenceApplication();
SetEvent(watcher->m_pShutdownEvent);

QueueUserWorkItem(RunNotificationCallback, watcher->_pApplication.get(), WT_EXECUTEDEFAULT);
return 0;
}


DWORD
WINAPI
FILE_WATCHER::RunNotificationCallback(
Expand All @@ -311,7 +378,6 @@ FILE_WATCHER::RunNotificationCallback(
{
// Recapture application instance into unique_ptr
auto pApplication = std::unique_ptr<AppOfflineTrackingApplication, IAPPLICATION_DELETER>(static_cast<AppOfflineTrackingApplication*>(pvArg));
DBG_ASSERT(pFileMonitor != NULL);
pApplication->OnAppOffline();

return 0;
Expand Down Expand Up @@ -359,6 +425,10 @@ FILE_WATCHER::StopMonitor()
InterlockedExchange(&_lStopMonitorCalled, 1);
// signal the file watch thread to exit
PostQueuedCompletionStatus(m_hCompletionPort, 0, FILE_WATCHER_SHUTDOWN_KEY, NULL);
WaitForMonitor(20000);
// See if this waits.
WaitForSingleObject(m_pShutdownEvent, 120000);

// Release application reference
_pApplication.reset(nullptr);
}
14 changes: 14 additions & 0 deletions src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "iapplication.h"
#include "HandleWrapper.h"
#include "Environment.h"
#include <sttimer.h>

#define FILE_WATCHER_SHUTDOWN_KEY (ULONG_PTR)(-1)
#define FILE_WATCHER_ENTRY_BUFFER_SIZE 4096
Expand Down Expand Up @@ -41,6 +42,14 @@ class FILE_WATCHER{
DWORD
WINAPI RunNotificationCallback(LPVOID);

static
VOID
WINAPI TimerCallback(_In_ PTP_CALLBACK_INSTANCE Instance,
_In_ PVOID Context,
_In_ PTP_TIMER Timer);

static DWORD WINAPI CopyAndShutdown(LPVOID);

HRESULT HandleChangeCompletion(DWORD cbCompletion);

HRESULT Monitor();
Expand All @@ -50,14 +59,19 @@ class FILE_WATCHER{
HandleWrapper<NullHandleTraits> m_hCompletionPort;
HandleWrapper<NullHandleTraits> m_hChangeNotificationThread;
HandleWrapper<NullHandleTraits> _hDirectory;
HandleWrapper<NullHandleTraits> m_pShutdownEvent;
volatile BOOL m_fThreadExit;
STTIMER m_Timer;
SRWLOCK m_copyLock{};
BOOL m_copied;

BUFFER _buffDirectoryChanges;
STRU _strFileName;
STRU _strDirectoryName;
STRU _strFullName;
LONG _lStopMonitorCalled {};
bool _fTrackDllChanges;
bool _fDllHadChanged;
std::wstring _shadowCopyPath;
OVERLAPPED _overlapped;
std::unique_ptr<AppOfflineTrackingApplication, IAPPLICATION_DELETER> _pApplication;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public async Task ShadowCopyE2EWorks()
deploymentParameters.HandlerSettings["shadowCopyDirectory"] = directory.FullName;
var deploymentResult = await DeployAsync(deploymentParameters);

DirectoryCopy(deploymentResult.ContentRoot, directory.FullName, copySubDirs: true);
//DirectoryCopy(deploymentResult.ContentRoot, Path.Combine(directory.FullName, "0"), copySubDirs: true);

await deploymentResult.HttpClient.GetStringAsync("Wow!");

Expand All @@ -164,7 +164,7 @@ public async Task ShadowCopyE2EWorks()

deploymentResult.AssertWorkerProcessStop();

EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.ShutdownFileChange(deploymentResult), Logger);
//EventLogHelpers.VerifyEventLogEvent(deploymentResult, EventLogHelpers.ShutdownFileChange(deploymentResult), Logger);
}

protected static DirectoryInfo CreateTempDirectory()
Expand Down

0 comments on commit a45a3dd

Please sign in to comment.