summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--osdep/WindowsEthernetTap.cpp20
1 files changed, 13 insertions, 7 deletions
diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp
index a7f0f14d..4a5d32a4 100644
--- a/osdep/WindowsEthernetTap.cpp
+++ b/osdep/WindowsEthernetTap.cpp
@@ -92,10 +92,8 @@ static const WindowsEthernetTapEnv WINENV;
// Only create or delete devices one at a time
static Mutex _systemTapInitLock;
-// Set to true if existing taps should close and reopen due to new device creation
-// This is a hack to get around what seems to be a bug that causes existing
-// devices to go into a coma after new device creation.
-static volatile bool _needReset = false;
+// Incrementing this causes everyone currently open to close and reopen
+static volatile int _systemTapResetStatus = 0;
} // anonymous namespace
@@ -271,8 +269,11 @@ WindowsEthernetTap::WindowsEthernetTap(
} else break; // no more keys or error occurred
}
- // Cause all existing taps to reset
- _needReset = true;
+ // When we create a new tap device from scratch, existing taps for
+ // some reason go into 'unplugged' state. This can be fixed by
+ // closing and re-opening them. Incrementing this causes all
+ // existing tap threads to do this.
+ ++_systemTapResetStatus;
}
if (_netCfgInstanceId.length() > 0) {
@@ -592,6 +593,7 @@ void WindowsEthernetTap::threadMain()
}
Utils::snprintf(tapPath,sizeof(tapPath),"\\\\.\\Global\\%s.tap",_netCfgInstanceId.c_str());
+ int prevTapResetStatus = _systemTapResetStatus;
while (_run) {
_tap = CreateFileA(tapPath,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,NULL);
if (_tap == INVALID_HANDLE_VALUE) {
@@ -695,7 +697,11 @@ void WindowsEthernetTap::threadMain()
ReadFile(_tap,tapReadBuf,sizeof(tapReadBuf),NULL,&tapOvlRead);
bool writeInProgress = false;
- while ((_run)&&(!_needReset)) {
+ while (_run) {
+ if (prevTapResetStatus != _systemTapResetStatus) {
+ prevTapResetStatus = _systemTapResetStatus;
+ break; // this will cause us to close and reopen the tap
+ }
DWORD r = WaitForMultipleObjectsEx(writeInProgress ? 3 : 2,wait4,FALSE,2500,TRUE);
if (!_run) break; // will also break outer while(_run)