=?UTF-8?Q?Iv=C3=A1n=20Matellanes=20?=: msvcirt: Implement ios object locking.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Jul 15 09:51:24 CDT 2015


Module: wine
Branch: master
Commit: 57fb458774d30935426800457861f70aaa007c8f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=57fb458774d30935426800457861f70aaa007c8f

Author: Iván Matellanes <matellanesivan at gmail.com>
Date:   Mon Jul 13 21:39:04 2015 +0200

msvcirt: Implement ios object locking.

---

 dlls/msvcirt/msvcirt.c       |  8 ++++++--
 dlls/msvcirt/tests/msvcirt.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 48fd682..f3c8c3c 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -985,7 +985,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 */
@@ -1119,7 +1121,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 62e1be9..db0df5e 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));
@@ -920,9 +946,27 @@ static void test_ios(void)
     ok(ios_obj.do_lock == -2, "expected -2 got %d\n", ios_obj.do_lock);
     ok(ios_obj.sb->do_lock == -1, "expected -1 got %d\n", ios_obj.sb->do_lock);
 
+    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 = 1;
     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)




More information about the wine-cvs mailing list