msvcirt: Implement ios stream locking.

This commit is contained in:
Iván Matellanes 2015-07-13 21:39:09 +02:00 committed by Alexandre Julliard
parent 57fb458774
commit 22f28d2923
2 changed files with 25 additions and 8 deletions

View File

@ -994,7 +994,8 @@ void __cdecl ios_lock(ios *this)
/* ?lockbuf@ios@@QEAAXXZ */ /* ?lockbuf@ios@@QEAAXXZ */
void __cdecl ios_lockbuf(ios *this) void __cdecl ios_lockbuf(ios *this)
{ {
FIXME("(%p) stub\n", this); TRACE("(%p)\n", this);
streambuf_lock(this->sb);
} }
/* ?lockc@ios@@KAXXZ */ /* ?lockc@ios@@KAXXZ */
@ -1130,7 +1131,8 @@ void __cdecl ios_unlock(ios *this)
/* ?unlockbuf@ios@@QEAAXXZ */ /* ?unlockbuf@ios@@QEAAXXZ */
void __cdecl ios_unlockbuf(ios *this) void __cdecl ios_unlockbuf(ios *this)
{ {
FIXME("(%p) stub\n", this); TRACE("(%p)\n", this);
streambuf_unlock(this->sb);
} }
/* ?unlockc@ios@@KAXXZ */ /* ?unlockc@ios@@KAXXZ */

View File

@ -132,6 +132,8 @@ static void (*__cdecl p_ios_clrlock)(ios*);
static void (*__cdecl p_ios_setlock)(ios*); static void (*__cdecl p_ios_setlock)(ios*);
static void (*__cdecl p_ios_lock)(ios*); static void (*__cdecl p_ios_lock)(ios*);
static void (*__cdecl p_ios_unlock)(ios*); static void (*__cdecl p_ios_unlock)(ios*);
static void (*__cdecl p_ios_lockbuf)(ios*);
static void (*__cdecl p_ios_unlockbuf)(ios*);
/* Emulate a __thiscall */ /* Emulate a __thiscall */
#ifdef __i386__ #ifdef __i386__
@ -238,6 +240,8 @@ static BOOL init(void)
SET(p_ios_setlock, "?setlock@ios@@QEAAXXZ"); SET(p_ios_setlock, "?setlock@ios@@QEAAXXZ");
SET(p_ios_lock, "?lock@ios@@QEAAXXZ"); SET(p_ios_lock, "?lock@ios@@QEAAXXZ");
SET(p_ios_unlock, "?unlock@ios@@QEAAXXZ"); SET(p_ios_unlock, "?unlock@ios@@QEAAXXZ");
SET(p_ios_lockbuf, "?lockbuf@ios@@QEAAXXZ");
SET(p_ios_unlockbuf, "?unlockbuf@ios@@QEAAXXZ");
} else { } else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2@YAPAXI@Z"); p_operator_new = (void*)GetProcAddress(msvcrt, "??2@YAPAXI@Z");
@ -274,6 +278,8 @@ static BOOL init(void)
SET(p_ios_setlock, "?setlock@ios@@QAAXXZ"); SET(p_ios_setlock, "?setlock@ios@@QAAXXZ");
SET(p_ios_lock, "?lock@ios@@QAAXXZ"); SET(p_ios_lock, "?lock@ios@@QAAXXZ");
SET(p_ios_unlock, "?unlock@ios@@QAAXXZ"); SET(p_ios_unlock, "?unlock@ios@@QAAXXZ");
SET(p_ios_lockbuf, "?lockbuf@ios@@QAAXXZ");
SET(p_ios_unlockbuf, "?unlockbuf@ios@@QAAXXZ");
} }
init_thiscall_thunk(); init_thiscall_thunk();
@ -821,15 +827,18 @@ struct ios_lock_arg
{ {
ios *ios_obj; ios *ios_obj;
HANDLE lock; HANDLE lock;
HANDLE release; HANDLE release[2];
}; };
static DWORD WINAPI lock_ios(void *arg) static DWORD WINAPI lock_ios(void *arg)
{ {
struct ios_lock_arg *lock_arg = arg; struct ios_lock_arg *lock_arg = arg;
p_ios_lock(lock_arg->ios_obj); p_ios_lock(lock_arg->ios_obj);
p_ios_lockbuf(lock_arg->ios_obj);
SetEvent(lock_arg->lock); SetEvent(lock_arg->lock);
WaitForSingleObject(lock_arg->release, INFINITE); WaitForSingleObject(lock_arg->release[0], INFINITE);
p_ios_unlockbuf(lock_arg->ios_obj);
WaitForSingleObject(lock_arg->release[1], INFINITE);
p_ios_unlock(lock_arg->ios_obj); p_ios_unlock(lock_arg->ios_obj);
return 0; return 0;
} }
@ -949,23 +958,29 @@ static void test_ios(void)
lock_arg.ios_obj = &ios_obj; lock_arg.ios_obj = &ios_obj;
lock_arg.lock = CreateEventW(NULL, FALSE, FALSE, NULL); lock_arg.lock = CreateEventW(NULL, FALSE, FALSE, NULL);
ok(lock_arg.lock != NULL, "CreateEventW failed\n"); ok(lock_arg.lock != NULL, "CreateEventW failed\n");
lock_arg.release = CreateEventW(NULL, FALSE, FALSE, NULL); lock_arg.release[0] = CreateEventW(NULL, FALSE, FALSE, NULL);
ok(lock_arg.release != NULL, "CreateEventW failed\n"); ok(lock_arg.release[0] != NULL, "CreateEventW failed\n");
lock_arg.release[1] = CreateEventW(NULL, FALSE, FALSE, NULL);
ok(lock_arg.release[1] != NULL, "CreateEventW failed\n");
thread = CreateThread(NULL, 0, lock_ios, (void*)&lock_arg, 0, NULL); thread = CreateThread(NULL, 0, lock_ios, (void*)&lock_arg, 0, NULL);
ok(thread != NULL, "CreateThread failed\n"); ok(thread != NULL, "CreateThread failed\n");
WaitForSingleObject(lock_arg.lock, INFINITE); WaitForSingleObject(lock_arg.lock, INFINITE);
locked = TryEnterCriticalSection(&ios_obj.lock); locked = TryEnterCriticalSection(&ios_obj.lock);
ok(locked == 0, "the ios object was not locked before\n"); ok(locked == 0, "the ios object was not locked before\n");
locked = TryEnterCriticalSection(&ios_obj.sb->lock);
ok(locked == 0, "the streambuf was not locked before\n");
SetEvent(lock_arg.release); SetEvent(lock_arg.release[0]);
SetEvent(lock_arg.release[1]);
WaitForSingleObject(thread, INFINITE); WaitForSingleObject(thread, INFINITE);
ios_obj.delbuf = 1; ios_obj.delbuf = 1;
call_func1(p_ios_dtor, &ios_obj); call_func1(p_ios_dtor, &ios_obj);
ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state); ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state);
CloseHandle(lock_arg.lock); CloseHandle(lock_arg.lock);
CloseHandle(lock_arg.release); CloseHandle(lock_arg.release[0]);
CloseHandle(lock_arg.release[1]);
CloseHandle(thread); CloseHandle(thread);
} }