dlls/kernel/comm.c: not releasing file descriptors?
Uwe Bonnes
bon at elektron.ikp.physik.tu-darmstadt.de
Thu Nov 3 03:10:20 CST 2005
>>>>> "Cihan" == Cihan Altinay <cihan at uq.edu.au> writes:
Cihan> Hi, I am trying to get G-Ware[1] to run under wine which provides
Cihan> a user interface to set up Echo Canceller Units made by
Cihan> ClearOne. The unit is connected to the serial port (com1 =
Cihan> ttyS0). The only way I can start the program at all is by
Cihan> configuring wine to act as Windows 95/98 and using native COM
Cihan> dll's. Furthermore, 'GWare.exe' starts 'PSRServe.exe' under
Cihan> native Windows but not under wine so I do the following in a bash
Cihan> file: wine C:\\Program\ Files\\G-Ware\\PSRServe.exe & wine
Cihan> C:\\Program\ Files\\G-Ware\\GWare.exe
Cihan> When I connect to the device I get endless
Cihan> fixme:comm:COMM_WaitCommEvent EV_RXFLAG not handled
Cihan> messages before communication breaks with this:
Cihan> wine client error:3bc: pipe: Too many open files
Cihan> After investigating I found out that indeed the number of open
Cihan> pipes to ttyS0 increases statically so I tried to find the reason
Cihan> and suspect the following (using the CVS checkout from 20051102):
Cihan> In the function COMM_WaitCommEvent in /dlls/kernel/comm.c line
Cihan> 2106 a thread is created for WaitCommEventService. However, in
Cihan> this branch of the if-statement fd is not released (using
Cihan> release_comm_fd). Releasing fd seems to work and the number of
Cihan> open pipes don't get past 200-300.
I wrote the WaitComEvent code. Probably
release_comm_fd( commio->handle, fd );
HeapFree(GetProcessHeap(), 0, commio );
needs to be executed for both cases. I am just compiling and testing...
Cihan> I am new to wine development and this is just a guess and I might
Cihan> be totally wrong. Unfortunately this does not fix the
Cihan> communication with the device (It reports timeouts and errors
Cihan> retrieving values etc). I guess this has to do with the first
Cihan> fixme messages I mentioned. Can anybody tell me what EV_RXFLAG
Cihan> is used for?
Google->WaitCommEvent->msdn.microsoft.com/library/en-us/devio/base/waitcommevent.asp
-> Look under lpEventMask
The program wants to be informed, when the device has sent an Event char. I
don't know about a way to do this in libc/kernel way in Unix. Actually the only
way I see is by polling the serial port andd checking for the event
character in our serial line service thread. Probably more places in the
comm code need to care for the Event character (the DCB structure e.g)
Cihan> Using WINEDEBUG=+tid,+comm I compared the output to
Cihan> what Sysinternals PortMon[2] gives me on native Windows and it
Cihan> really looks promising. Is there a way to display the actual data
Cihan> that was sent/received through the serial port? I tried
Cihan> WINEDEBUG=+io which does not work.
Sending/receiving is done via kernel/file.c
Following patch traces all write/reads, so you have to manually look for
those on the serial line.
retrieving revision 1.40
diff -u -w -r1.40 file.c
--- wine/dlls/kernel/file.c 11 Jul 2005 14:23:46 -0000 1.40
+++ wine/dlls/kernel/file.c 5 Sep 2005 08:25:54 -0000
@@ -46,6 +46,7 @@
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(file);
+WINE_DECLARE_DEBUG_CHANNEL(fileio);
HANDLE dos_handles[DOS_TABLE_SIZE];
@@ -377,6 +378,15 @@
if (status != STATUS_PENDING && bytesRead)
*bytesRead = io_status->Information;
+ if (TRACE_ON(fileio) && bytesRead && *bytesRead)
+ {
+ int i;
+ DPRINTF("ReadFile %9ld Bytes from %p: 0x", *bytesRead, hFile);
+ for(i=0; i<*bytesRead && i<20; i++)
+ DPRINTF("%02x",((unsigned char*)buffer)[i]);
+ DPRINTF(" %s\n",debugstr_an((unsigned char*)buffer,(*bytesRead>20)?20:*bytesRead));
+ }
+
if (status && status != STATUS_END_OF_FILE && status != STATUS_TIMEOUT)
{
SetLastError( RtlNtStatusToDosError(status) );
@@ -433,6 +443,15 @@
TRACE("%p %p %ld %p %p\n", hFile, buffer, bytesToWrite, bytesWritten, overlapped );
+ if (TRACE_ON(fileio) && bytesToWrite)
+ {
+ int i;
+ DPRINTF("WriteFile %8ld Bytes from %p: 0x", bytesToWrite, hFile);
+ for(i=0; i<bytesToWrite && i<20; i++)
+ DPRINTF("%02x",((unsigned char*)buffer)[i]);
+ DPRINTF(" %s\n",debugstr_an(buffer,(bytesToWrite>20)?20:bytesToWrite));
+ }
+
if (is_console_handle(hFile))
return WriteConsoleA(hFile, buffer, bytesToWrite, bytesWritten, NULL);
--
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
More information about the wine-devel
mailing list