aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/sys
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2013-02-23 00:46:26 +0100
committerRickard Green <[email protected]>2013-02-23 00:46:26 +0100
commit4326dac8464123a687af32c3fcbbd53c7e0a4bbc (patch)
treee875038d336d5534629da326f69c3ea1e078fbb9 /erts/emulator/sys
parent4258b0f65d1b4a09e735a683872f332cf275a1fb (diff)
parent0e8b4f227fc82715ff85978613d161ffb13c22d1 (diff)
downloadotp-4326dac8464123a687af32c3fcbbd53c7e0a4bbc.tar.gz
otp-4326dac8464123a687af32c3fcbbd53c7e0a4bbc.tar.bz2
otp-4326dac8464123a687af32c3fcbbd53c7e0a4bbc.zip
Merge branch 'rickard/win-drv-bugfix/OTP-10803'
* rickard/win-drv-bugfix/OTP-10803: Fix close_active_handle() properly
Diffstat (limited to 'erts/emulator/sys')
-rwxr-xr-xerts/emulator/sys/win32/sys.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index cfdf5c9b62..e0422de026 100755
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -752,8 +752,8 @@ release_driver_data(DriverData* dp)
struct handles_to_be_closed {
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ DriverData *drv_data[MAXIMUM_WAIT_OBJECTS];
unsigned cnt;
- DriverData *dp;
};
static struct handles_to_be_closed* htbc_curr = NULL;
CRITICAL_SECTION htbc_lock;
@@ -771,15 +771,18 @@ static void close_active_handle(DriverData *dp, HANDLE handle)
htbc = (struct handles_to_be_closed*) erts_alloc(ERTS_ALC_T_DRV_TAB,
sizeof(*htbc));
htbc->handles[0] = CreateAutoEvent(FALSE);
+ htbc->drv_data[0] = NULL;
htbc->cnt = 1;
- htbc->dp = dp;
- refer_driver_data(dp); /* Need to keep driver data until we have
- closed the event; outstanding operation
- might write into it.. */
thread = (HANDLE *) _beginthreadex(NULL, 0, threaded_handle_closer, htbc, 0, &tid);
CloseHandle(thread);
}
- htbc->handles[htbc->cnt++] = handle;
+ i = htbc->cnt++;
+ htbc->handles[i] = handle;
+ htbc->drv_data[i] = dp;
+ if (dp)
+ refer_driver_data(dp); /* Need to keep driver data until we have
+ closed the event; outstanding operation
+ might write into it.. */
SetEvent(htbc->handles[0]);
htbc_curr = htbc;
LeaveCriticalSection(&htbc_lock);
@@ -811,8 +814,13 @@ threaded_handle_closer(LPVOID param)
default:
ix = res - WAIT_OBJECT_0;
if (ix > 0 && ix < htbc->cnt) {
+ int move_ix;
CloseHandle(htbc->handles[ix]);
- htbc->handles[ix] = htbc->handles[--htbc->cnt];
+ if (htbc->drv_data[ix])
+ unrefer_driver_data(htbc->drv_data[ix]);
+ move_ix = --htbc->cnt;
+ htbc->handles[ix] = htbc->handles[move_ix];
+ htbc->drv_data[ix] = htbc->drv_data[move_ix];
}
}
if (htbc != htbc_curr) {
@@ -828,7 +836,7 @@ threaded_handle_closer(LPVOID param)
}
LeaveCriticalSection(&htbc_lock);
CloseHandle(htbc->handles[0]);
- unrefer_driver_data(htbc->dp);
+ ASSERT(!htbc->drv_data[0]);
erts_free(ERTS_ALC_T_DRV_TAB, htbc);
DEBUGF(("threaded_handle_closer %p terminating\r\n", htbc));
return 0;