Ver código fonte

Fix to tap reset code in Windows tap connector.

Adam Ierymenko 10 anos atrás
pai
commit
241f308334
1 arquivos alterados com 13 adições e 7 exclusões
  1. 13 7
      osdep/WindowsEthernetTap.cpp

+ 13 - 7
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)