[2/4] msvcirt: Implement ios object locking
Iván Matellanes
matellanesivan at gmail.com
Tue Jul 7 14:00:37 CDT 2015
---
dlls/msvcirt/msvcirt.c | 8 ++++++--
dlls/msvcirt/tests/msvcirt.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index a2f5189..2ecc380 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -981,7 +981,9 @@ LONG* __thiscall ios_iword(const ios *this, int index)
/* ?lock at ios@@QEAAXXZ */
void __cdecl ios_lock(ios *this)
{
- FIXME("(%p) stub\n", this);
+ TRACE("(%p)\n", this);
+ if (this->do_lock < 0)
+ EnterCriticalSection(&this->lock);
}
/* ?lockbuf at ios@@QAAXXZ */
@@ -1113,7 +1115,9 @@ ostream* __thiscall ios_tie_get(const ios *this)
/* ?unlock at ios@@QEAAXXZ */
void __cdecl ios_unlock(ios *this)
{
- FIXME("(%p) stub\n", this);
+ TRACE("(%p)\n", this);
+ if (this->do_lock < 0)
+ LeaveCriticalSection(&this->lock);
}
/* ?unlockbuf at ios@@QAAXXZ */
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index f53afd8..0d87818 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -130,6 +130,8 @@ static void (*__thiscall p_ios_init)(ios*, streambuf*);
static void (*__thiscall p_ios_dtor)(ios*);
static void (*__cdecl p_ios_clrlock)(ios*);
static void (*__cdecl p_ios_setlock)(ios*);
+static void (*__cdecl p_ios_lock)(ios*);
+static void (*__cdecl p_ios_unlock)(ios*);
/* Emulate a __thiscall */
#ifdef __i386__
@@ -234,6 +236,8 @@ static BOOL init(void)
SET(p_ios_dtor, "??1ios@@UEAA at XZ");
SET(p_ios_clrlock, "?clrlock at ios@@QEAAXXZ");
SET(p_ios_setlock, "?setlock at ios@@QEAAXXZ");
+ SET(p_ios_lock, "?lock at ios@@QEAAXXZ");
+ SET(p_ios_unlock, "?unlock at ios@@QEAAXXZ");
} else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z");
@@ -268,6 +272,8 @@ static BOOL init(void)
SET(p_ios_dtor, "??1ios@@UAE at XZ");
SET(p_ios_clrlock, "?clrlock at ios@@QAAXXZ");
SET(p_ios_setlock, "?setlock at ios@@QAAXXZ");
+ SET(p_ios_lock, "?lock at ios@@QAAXXZ");
+ SET(p_ios_unlock, "?unlock at ios@@QAAXXZ");
}
init_thiscall_thunk();
@@ -811,10 +817,30 @@ static void test_streambuf(void)
CloseHandle(thread);
}
+struct ios_lock_arg
+{
+ ios *ios_obj;
+ HANDLE lock;
+ HANDLE release;
+};
+
+static DWORD WINAPI lock_ios(void *arg)
+{
+ struct ios_lock_arg *lock_arg = arg;
+ p_ios_lock(lock_arg->ios_obj);
+ SetEvent(lock_arg->lock);
+ WaitForSingleObject(lock_arg->release, INFINITE);
+ p_ios_unlock(lock_arg->ios_obj);
+ return 0;
+}
+
static void test_ios(void)
{
ios ios_obj, ios_obj2;
streambuf *psb;
+ struct ios_lock_arg lock_arg;
+ HANDLE thread;
+ BOOL locked;
memset(&ios_obj, 0xab, sizeof(ios));
memset(&ios_obj2, 0xab, sizeof(ios));
@@ -913,9 +939,28 @@ static void test_ios(void)
p_ios_setlock(&ios_obj);
ok(ios_obj.do_lock == -2, "expected -2 got %d\n", ios_obj.do_lock);
+ ios_obj.do_lock = -1;
+ lock_arg.ios_obj = &ios_obj;
+ lock_arg.lock = CreateEventW(NULL, FALSE, FALSE, NULL);
+ ok(lock_arg.lock != NULL, "CreateEventW failed\n");
+ lock_arg.release = CreateEventW(NULL, FALSE, FALSE, NULL);
+ ok(lock_arg.release != NULL, "CreateEventW failed\n");
+ thread = CreateThread(NULL, 0, lock_ios, (void*)&lock_arg, 0, NULL);
+ ok(thread != NULL, "CreateThread failed\n");
+ WaitForSingleObject(lock_arg.lock, INFINITE);
+
+ locked = TryEnterCriticalSection(&ios_obj.lock);
+ ok(locked == 0, "the ios object was not locked before\n");
+
+ SetEvent(lock_arg.release);
+ WaitForSingleObject(thread, INFINITE);
+
ios_obj.delbuf = 0;
call_func1(p_ios_dtor, &ios_obj);
ok(ios_obj.state == IOSTATE_badbit, "expected %x got %x\n", IOSTATE_badbit, ios_obj.state);
+ CloseHandle(lock_arg.lock);
+ CloseHandle(lock_arg.release);
+ CloseHandle(thread);
}
START_TEST(msvcirt)
--
2.1.4
More information about the wine-patches
mailing list