Dmitry Timoshkov : kernel32/tests: Make test_waittxempty() use overlapped IO to avoid waiting forever when a kernel driver doesn' t support TIOCGICOUNT/TIOCSERGETLSR ioctl.

Alexandre Julliard julliard at winehq.org
Thu Aug 15 13:12:47 CDT 2013


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

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Thu Aug 15 16:40:29 2013 +0900

kernel32/tests: Make test_waittxempty() use overlapped IO to avoid waiting forever when a kernel driver doesn't support TIOCGICOUNT/TIOCSERGETLSR ioctl.

Most of Linux USB-serial drivers don't support these ioctls.

---

 dlls/kernel32/tests/comm.c |  102 ++++++++++++++++++++++++++++++-------------
 1 files changed, 71 insertions(+), 31 deletions(-)

diff --git a/dlls/kernel32/tests/comm.c b/dlls/kernel32/tests/comm.c
index 81953cb..b393db4 100644
--- a/dlls/kernel32/tests/comm.c
+++ b/dlls/kernel32/tests/comm.c
@@ -780,59 +780,99 @@ static void test_waittxempty(void)
     DCB dcb;
     COMMTIMEOUTS timeouts;
     char tbuf[]="test_waittxempty";
-    DWORD before, after, written, timediff, evtmask = 0;
-    BOOL res_write, res;
+    DWORD before, after, bytes, timediff, evtmask;
+    BOOL res;
     DWORD baud = SLOWBAUD;
+    OVERLAPPED ovl_write, ovl_wait;
 
-    hcom = test_OpenComm(FALSE);
+    hcom = test_OpenComm(TRUE);
     if (hcom == INVALID_HANDLE_VALUE) return;
 
     /* set a low baud rate to have ample time*/
-    ok(GetCommState(hcom, &dcb), "GetCommState failed\n");
+    res = GetCommState(hcom, &dcb);
+    ok(res, "GetCommState error %d\n", GetLastError());
     dcb.BaudRate = baud;
     dcb.ByteSize = 8;
     dcb.Parity = NOPARITY;
     dcb.fRtsControl=RTS_CONTROL_ENABLE;
     dcb.fDtrControl=DTR_CONTROL_ENABLE;
     dcb.StopBits = ONESTOPBIT;
-    ok(SetCommState(hcom, &dcb), "SetCommState failed\n");
+    res = SetCommState(hcom, &dcb);
+    ok(res, "SetCommState error %d\n", GetLastError());
 
     ZeroMemory( &timeouts, sizeof(timeouts));
     timeouts.ReadTotalTimeoutConstant = TIMEOUT;
-    ok(SetCommTimeouts(hcom, &timeouts),"SetCommTimeouts failed\n");
+    res = SetCommTimeouts(hcom, &timeouts);
+    ok(res,"SetCommTimeouts error %d\n", GetLastError());
 
-    ok(SetupComm(hcom,1024,1024),"SetUpComm failed\n");
-    ok(SetCommMask(hcom, EV_TXEMPTY), "SetCommMask failed\n");
+    res = SetupComm(hcom, 1024, 1024);
+    ok(res, "SetUpComm error %d\n", GetLastError());
+
+    /* calling SetCommMask after WriteFile leads to WaitCommEvent failures
+     * due to timeout (no events) under testbot VMs and VirtualBox
+     */
+    res = SetCommMask(hcom, EV_TXEMPTY);
+    ok(res, "SetCommMask error %d\n", GetLastError());
 
+    SetLastError(0xdeadbeef);
+    res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, NULL);
+todo_wine
+    ok(!res, "WriteFile on an overlapped handle without ovl structure should fail\n");
+todo_wine
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+
+    S(U(ovl_write)).Offset = 0;
+    S(U(ovl_write)).OffsetHigh = 0;
+    ovl_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
     before = GetTickCount();
-    res_write=WriteFile(hcom, tbuf, sizeof(tbuf), &written, NULL);
+    SetLastError(0xdeadbeef);
+    res = WriteFile(hcom, tbuf, sizeof(tbuf), &bytes, &ovl_write);
     after = GetTickCount();
-    ok(res_write == TRUE, "WriteFile failed\n");
-    ok(written == sizeof(tbuf),
-       "WriteFile: Unexpected write_size %d\n", written);
-
-    trace("WriteFile succeeded, took %d ms to write %d Bytes at %d Baud\n",
-	  after - before, written, baud);
-
+todo_wine
+    ok(!res && GetLastError() == ERROR_IO_PENDING, "WriteFile returned %d, error %d\n", res, GetLastError());
+todo_wine
+    ok(!bytes, "expected 0, got %u\n", bytes);
+    ok(after - before == 0, "WriteFile took %d ms to write %d Bytes at %d Baud\n",
+       after - before, bytes, baud);
+    /* don't wait for WriteFile completion */
+
+    S(U(ovl_wait)).Offset = 0;
+    S(U(ovl_wait)).OffsetHigh = 0;
+    ovl_wait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+    evtmask = 0;
     before = GetTickCount();
-    res = WaitCommEvent(hcom, &evtmask, NULL);
+    SetLastError(0xdeadbeef);
+    res = WaitCommEvent(hcom, &evtmask, &ovl_wait);
+    ok(!res && GetLastError() == ERROR_IO_PENDING, "WaitCommEvent error %d\n", GetLastError());
+    res = WaitForSingleObject(ovl_wait.hEvent, TIMEOUT);
+todo_wine
+    ok(res == WAIT_OBJECT_0, "WaitCommEvent failed with a timeout\n");
+    if (res == WAIT_OBJECT_0)
+    {
+        res = GetOverlappedResult(hcom, &ovl_wait, &bytes, FALSE);
+        ok(res, "GetOverlappedResult reported error %d\n", GetLastError());
+        ok(bytes == sizeof(evtmask), "expected %u, written %u\n", (UINT)sizeof(evtmask), bytes);
+        res = TRUE;
+    }
+    else res = FALSE;
     after = GetTickCount();
-
-    ok(res == TRUE, "WaitCommEvent failed\n");
-    ok((evtmask & EV_TXEMPTY),
-                 "WaitCommEvent: Unexpected EvtMask 0x%08x, expected 0x%08x\n",
-		 evtmask, EV_TXEMPTY);
+todo_wine
+    ok(res, "WaitCommEvent error %d\n", GetLastError());
+todo_wine
+    ok(evtmask & EV_TXEMPTY, "WaitCommEvent: expected EV_TXEMPTY, got %#x\n", evtmask);
+    CloseHandle(ovl_wait.hEvent);
 
     timediff = after - before;
-
-    trace("WaitCommEvent for EV_TXEMPTY took %d ms\n", timediff);
-    /* 050604: This shows a difference between XP (tested with mingw compiled crosstest):
-       XP returns Writefile only after everything went out of the Serial port,
-       while wine returns immediately.
-       Thus on XP, WaintCommEvent after setting the CommMask for EV_TXEMPTY
-       nearly return immediate,
-       while on wine the most time is spent here
-    */
+    trace("WaitCommEvent for EV_TXEMPTY took %d ms (timeout %d)\n", timediff, TIMEOUT);
+todo_wine
+    ok(timediff < 900, "WaitCommEvent used %d ms for waiting\n", timediff);
+
+    res = WaitForSingleObject(ovl_write.hEvent, 0);
+    ok(res == WAIT_OBJECT_0, "WriteFile failed with a timeout\n");
+    res = GetOverlappedResult(hcom, &ovl_write, &bytes, FALSE);
+    ok(res, "GetOverlappedResult reported error %d\n", GetLastError());
+    ok(bytes == sizeof(tbuf), "expected %u, written %u\n", (UINT)sizeof(tbuf), bytes);
+    CloseHandle(ovl_write.hEvent);
 
     CloseHandle(hcom);
 }




More information about the wine-cvs mailing list