> The system I'm building seperates (through an API) the queueing code and the
> interface code.  This is with a view to implementing 'modules' for different
> types of device/interface without affecting any of the queueing and
> application side code.
>
> The initial device it'll writing the code for will be syncronous, and the
> ACK'ing issues will not be a problem.  I'll implement a state machine to
> handle the protocol.  All I really need to know at this stage are the issues
> I've already outlined concerning the sharing of file descriptors and
> fileevent callbacks.

Well, I would still recommend doing it with two threads.  If the device
is synchronous, then it's pretty easy.

Assumption: the reader thread can distinguish between an ACK and a data
packet.

The reader thread reads from the device.  When it gets a data packet, it
puts it on the I-queue, sets the "send ACK" flag, and signals the writer
thread.  When it gets an ACK, it sets the "received ACK" flag and
signals the writer thread.

The writer thread waits on an Ns_Cond. When the cond is signalled, or
the wait times out, the writer follows this algorithm:

    if the "send ACK" flag is set then
        send an ACK
        clear the "send ACK" flag
    endif

    if the "awaiting ACK" flag is set then
        if the "received ACK" flag is set then
            discard the packet that got ACK'd
            clear the "received ACK" flag
            clear the "awaiting ACK" flag
        else if enough time has passed since I last sent the packet then
            send the packet again
        endif
    endif

    // Note: this is "if", not "else if".
    if the "awaiting ACK" flag is not set then
        if there is a packet in the O-queue then
            remove the packet from the O-queue
            send the packet
            save the packet in case we need to retransmit it
            set the "awaiting ACK" flag
        endif
    endif

The only thing the reader ever waits for is bytes from the device.  The
only things the writer ever waits for are an Ns_Cond signal and a
timeout.

Personally, I would implement this in C.  However, if the device is not
exclusive-open, then you can implement it in Tcl without needing any
extra C code.  Just open it once in the reader thread and once in the
writer thread.  Both threads can open it in blocking mode; neither
thread needs to use file events.

Reply via email to