Hello Wine Developers,

i'd like to ask for some opinions on implementing some features for
serial communications support.

For applications to successfully use serial ports in Wine, the
following is most likely needed:

1) wine server support of comm ports
2) support for overlapped (asynchronous) I/O
3) support for WaitCommEvent

These are my ideas on how each feature could be implemented (aka
Design Doco):


*** Wine server support

Currently, in the wineserver comm ports are treated as standard files.
This works for some simple applications, but is not enough any
sophisticated use of COMM ports. 

i am planning to create a new kernel32 object, "port" which will the
server side support for COMM handles. port objects will store the
COMMTIMEOUTS, comm error state, commevents (re: Get/SetCommEvents) and
perhaps the current DCB. Instead of using REQ_CREATE_FILE to open COMM
ports, the new request REQ_CREATE_PORT will be used. REQ_CREATE_PORT
will be pretty much the same as it's FILE counterpart, but will create
a PORT instead.

With the port object, requests to get and set port timeouts, eventmask
and DCB will be added. eg.

REQ_SET_TIMEOUTS, REQ_GET_TIMEOUTS, REQ_SET_EVENTMASK,
REQ_GET_EVENTMASK.

Question: Should the DCB stored in the port object, or should it be
reconstructed from the (Linux?) kernel upon request?


*** OVERLAPPED (asynchronous) I/O support

Asynchronous I/O can be performed on COMM ports, sockets and devices
in Win9x, and files, pipes, etc in WinNT. Alexandre advised me that it
would be best to implement asynchronous I/O in the server in a generic
fashion, so that it is easy for objects other than COMM ports to take
advantage of. 

My current idea is the object_ops structure in the server
(server/object.h) would have two extra function pointers added to it,
one for async_read, the other for async_write.

Overlapped opperations would work as follows:

Each object maintains a list (obj->async_list) of pending async I/O
operations, keyed by object handle and client side overlapped struct
pointer.

A client requesting overlapped I/O (ReadFile, WriteFile,
WaitCommEvent, etc) first stores the HANDLE in the
OVERLAPPED.InternalHigh), if necessary the number of bytes to be
read/written in OVERLAPPED.OffsetHigh, and the number of bytes read so
far (if any) in OVERLAPPED.Offset. The OVERLAPPED.Internal field is
unused, and OVERLAPPED.hEvent is filled by the calling program.

When the server receives a request for overlapped I/O, the operation
would be queued to obj->async_list. The overlapped operation would
become a select user in the server, and perhaps a timeout user if
necessary.

When the object is alerted by obj_ops->poll_event(), it first removes
itself from the select users queue (to prevent busy loops), then
queues an Asynchronous Procedure Call (APC) to the thread that started
the Overlapped operation, using thread_queue_apc. The APC function
would be set when the handle is opened (eg. by REQ_CREATE_PORT). The
argument of the APC would be the pointer to the client side overlapped
structure.

When the APC is called, it calls the server back requesting details on
the asynchronous operation to be called. The server uses the handle
stored in OVERLAPPED.InternalHigh and the client overlapped pointer to
identify the overlapped operation. After finishing reading or writing,
again the client informs the server of the result (continue, complete,
fail, etc) of the operation.

If the operation is incomplete (result continue), the server adds the
object to the select user queue again.

When the client finishes the async operation, it sets the
OVERLAPPED.hEvent flag. GetOverlappedResult simply waits the hEvent
flag using WaitSignleObjectEx with bAlertable enabled.

In summary the following server requests would be created:

REQ_CREATE_PORT   (for COMM ports only)
REQ_WAITCOMMEVENT
REQ_ASYNC_READ
REQ_ASYNC_WRITE
REQ_ASYNC_INFO  (used by client APC to get operation info)
REQ_ASYNC_RESULT (used by client APC tell server the result)

CancelIo is implemented using REQ_ASYNC_RESULT.


Some questions (about Async):
* Is it correct to use the thread that initiated the asynchrouous
operation for the APC? (it will be alertable when it calls
GetOverlappedResult)
* Is there any way to reduce the number of server requests? (i'm
worried that three requests per async callback will be slow.)
* Does anybody know the contents of OVERLAPPED in Windoze? (is it safe
to assume that applications don't play with anything but hEvent?...
what about the IsOverlappedCompelete macro?)


Support for WaitCommEvent. (in Linux)

(bear with me, i'm a bit tired and don't have Linux's source in front
of me)

To support anything other than EV_RXCHAR and EV_TXEMPTY will require
some kernel hacking, as the Linux kernel provides no way to be alerted
on deltas in modem state...

The way i though of to support all the waitable flags of WaitCommEvent
(EV_CTS, EV_DSR, EV_RLSD, EV_BREAK, etc) was to create three Linux
ioctls that enable selecting on changes of state in the serial port.
These would be something like TCIOM_SETMASK, TCIOM_GETMASK,
TCIOM_GETEVENTS.

Basic sequence would be (in pseudo code):

/* set which events select is responsive to */
ioctl(fd,TCIOM_SETMASK, &event_mask);
select(fd,POLLIN); /* wineserver's main select call */
/* which event triggered select? */
ioctl(fd,TCIOM_GETEVENTS, &events);

TCIOM_GETMASK would be used in GetCommMask.

This would require changes to linux/drivers/char/n_tty.c, and
linux/drivers/char/serial.c

Question: i haven't followed Linux 2.3.x development closely. Does
anybody know of any changes to 2.3.x that could be used to support
WaitCommEvent?


OK, if you've gotten this far, you may be interested in having a look
at some source code that attempts to implement async I/O as described
above. If so, mail me. It compiles, but i haven't completed debugging
yet, so it's not really ready for release...

Sorry for my English... though English is my native language ;-)

Mike






------------------------------------------
mailto:[EMAIL PROTECTED]
ph +86 010 82302880

__________________________________________________________________
Get your own free web email at http://www.looksmart.com.au
LookSmart Australia

Reply via email to