mirror of
https://github.com/moonlight-stream/Internet-Hosting-Tool.git
synced 2025-07-01 15:26:54 +00:00
Improve performance and reliability when stopping MISS
This commit is contained in:
parent
624af65b55
commit
4d197cae02
@ -57,6 +57,9 @@ static struct port_entry {
|
|||||||
|
|
||||||
static const int k_WolPorts[] = { 9, 47009 };
|
static const int k_WolPorts[] = { 9, 47009 };
|
||||||
|
|
||||||
|
static HANDLE s_StopEvent;
|
||||||
|
static CRITICAL_SECTION s_PortMappingUpdateLock;
|
||||||
|
|
||||||
bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const char* myAddr, int port, bool enable, bool indefinite, bool validationPass)
|
bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const char* myAddr, int port, bool enable, bool indefinite, bool validationPass)
|
||||||
{
|
{
|
||||||
char intClient[16];
|
char intClient[16];
|
||||||
@ -384,17 +387,21 @@ bool UPnPHandleDeviceList(struct UPNPDev* list, bool enable, char* lanAddrOverri
|
|||||||
|
|
||||||
// Validate the rules are present and correct if they claimed to be added successfully
|
// Validate the rules are present and correct if they claimed to be added successfully
|
||||||
if (success && enable) {
|
if (success && enable) {
|
||||||
// Wait 10 seconds for the router state to quiesce
|
// Wait 10 seconds for the router state to quiesce or the stop event to be set
|
||||||
printf("Waiting before UPnP port validation...");
|
printf("Waiting before UPnP port validation...");
|
||||||
Sleep(10000);
|
if (WaitForSingleObject(s_StopEvent, 10000) == WAIT_TIMEOUT) {
|
||||||
printf("done" NL);
|
printf("done" NL);
|
||||||
|
|
||||||
// Perform the validation pass (converting any now missing entries to permanent ones)
|
// Perform the validation pass (converting any now missing entries to permanent ones)
|
||||||
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
||||||
if (!UPnPMapPort(&urls, &data, k_Ports[i].proto, portMappingInternalAddress, k_Ports[i].port, enable, false, true)) {
|
if (!UPnPMapPort(&urls, &data, k_Ports[i].proto, portMappingInternalAddress, k_Ports[i].port, enable, false, true)) {
|
||||||
success = false;
|
success = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
printf("aborted" NL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeUPNPUrls(&urls);
|
FreeUPNPUrls(&urls);
|
||||||
@ -579,6 +586,12 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
|||||||
ipv4Devs = getUPnPDevicesByAddress(addr);
|
ipv4Devs = getUPnPDevicesByAddress(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Abort if this is an add/update request and we're stopping
|
||||||
|
if (enable && WaitForSingleObject(s_StopEvent, 0) == WAIT_OBJECT_0) {
|
||||||
|
printf("Aborting port mapping update due to stop request" NL);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
// Use the delay of discovery to also allow the NAT-PMP endpoint time to respond
|
// Use the delay of discovery to also allow the NAT-PMP endpoint time to respond
|
||||||
if (natPmpErr >= 0) {
|
if (natPmpErr >= 0) {
|
||||||
natpmpresp_t response;
|
natpmpresp_t response;
|
||||||
@ -876,11 +889,23 @@ DWORD WINAPI GameStreamStateChangeThread(PVOID Context)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Initialize()
|
||||||
|
{
|
||||||
|
// Create the stop event
|
||||||
|
s_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
if (s_StopEvent == NULL) {
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeCriticalSection(&s_PortMappingUpdateLock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int Run(bool standaloneExe)
|
int Run(bool standaloneExe)
|
||||||
{
|
{
|
||||||
HANDLE ifaceChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
HANDLE ifaceChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||||
HANDLE gsChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
HANDLE gsChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||||
HANDLE events[2] = { ifaceChangeEvent, gsChangeEvent };
|
HANDLE events[3] = { ifaceChangeEvent, gsChangeEvent, s_StopEvent };
|
||||||
|
|
||||||
ResetLogFile(standaloneExe);
|
ResetLogFile(standaloneExe);
|
||||||
|
|
||||||
@ -915,7 +940,17 @@ int Run(bool standaloneExe)
|
|||||||
printf("GameStream is OFF!" NL);
|
printf("GameStream is OFF!" NL);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePortMappings(gameStreamEnabled);
|
// Acquire the mapping lock and update port mappings
|
||||||
|
if (TryEnterCriticalSection(&s_PortMappingUpdateLock)) {
|
||||||
|
// If the stop event is set, bail out now
|
||||||
|
if (WaitForSingleObject(s_StopEvent, 0) == WAIT_OBJECT_0) {
|
||||||
|
LeaveCriticalSection(&s_PortMappingUpdateLock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdatePortMappings(gameStreamEnabled);
|
||||||
|
LeaveCriticalSection(&s_PortMappingUpdateLock);
|
||||||
|
}
|
||||||
|
|
||||||
// Refresh when half the duration is expired or if an IP interface
|
// Refresh when half the duration is expired or if an IP interface
|
||||||
// change event occurs.
|
// change event occurs.
|
||||||
@ -939,6 +974,10 @@ int Run(bool standaloneExe)
|
|||||||
printf("Woke up for GameStream state change notification after %lld seconds" NL,
|
printf("Woke up for GameStream state change notification after %lld seconds" NL,
|
||||||
(GetTickCount64() - beforeSleepTime) / 1000);
|
(GetTickCount64() - beforeSleepTime) / 1000);
|
||||||
}
|
}
|
||||||
|
else if (ret == WAIT_OBJECT_0 + 2) {
|
||||||
|
printf("Woke up for stop notification" NL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
ResetLogFile(standaloneExe);
|
ResetLogFile(standaloneExe);
|
||||||
|
|
||||||
@ -960,14 +999,21 @@ HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpConte
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
|
|
||||||
case SERVICE_CONTROL_STOP:
|
case SERVICE_CONTROL_STOP:
|
||||||
|
// Stop future port mapping updates
|
||||||
|
SetEvent(s_StopEvent);
|
||||||
|
|
||||||
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||||
ServiceStatus.dwControlsAccepted = 0;
|
ServiceStatus.dwControlsAccepted = 0;
|
||||||
|
ServiceStatus.dwWaitHint = 120 * 1000; // 2 minutes
|
||||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||||
|
|
||||||
|
// Remove existing port mappings
|
||||||
|
EnterCriticalSection(&s_PortMappingUpdateLock);
|
||||||
printf("Removing UPnP/NAT-PMP/PCP rules after service stop request\n");
|
printf("Removing UPnP/NAT-PMP/PCP rules after service stop request\n");
|
||||||
UpdatePortMappings(false);
|
UpdatePortMappings(false);
|
||||||
|
LeaveCriticalSection(&s_PortMappingUpdateLock);
|
||||||
|
|
||||||
printf("The service is stopping\n");
|
printf("The service is stopping now\n");
|
||||||
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
@ -989,6 +1035,14 @@ ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = Initialize();
|
||||||
|
if (err != 0) {
|
||||||
|
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||||
|
ServiceStatus.dwWin32ExitCode = err;
|
||||||
|
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||||
ServiceStatus.dwServiceSpecificExitCode = 0;
|
ServiceStatus.dwServiceSpecificExitCode = 0;
|
||||||
ServiceStatus.dwWin32ExitCode = NO_ERROR;
|
ServiceStatus.dwWin32ExitCode = NO_ERROR;
|
||||||
@ -1024,8 +1078,8 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (argc == 2 && !strcmp(argv[1], "exe")) {
|
if (argc == 2 && !strcmp(argv[1], "exe")) {
|
||||||
Run(true);
|
Initialize();
|
||||||
return 0;
|
return Run(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return StartServiceCtrlDispatcher(ServiceTable);
|
return StartServiceCtrlDispatcher(ServiceTable);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user