-=> Quoting Jerry Coffin to Darin Mcbride
JC> On (18 Aug 97) Darin Mcbride wrote to Jerry Coffin...
DM> I'm trying, mostly for the sake of learning, to write a simple
DM> multi-threaded comm class. Most of it seems to work, so far, except
DM> the queues. I'd like to have a write queue and read queue. That
DM> seems simple - there's a deque in the STL.
JC> ...or maybe not so simple -- quite a few versions of STL aren't safe
JC> for multithreaded use. I've been working on making the version that
JC> came with VC++ 4.2 completely thread-safe, and though I'm not done yet,
JC> it's the only one I've personally seen that was even close.
Hmmmm... true. What do you do to make it "thread-safe"? Any semaphoring, or
just the volatile, letting the user do the semaphores? Now that you mention
it, someone was advertising about having a thread-safe version of STL
available... let's see if I can find the message... SGI says it's on:
http://www.sgi.com/Technology/STL.
JC> Is your class driving the hardware directly, or does it work through a
JC> device driver? (E.g. under OS/2)
Device driver, of course. :-) This'd be a bigger mess if I were forced to
do this under DOS. Mind you, between the two of us, I'd say we'd have a hard
time giving half a darn about DOS - and that's assuming you give a full darn
about DOS! ;-)
DM> Except that it doesn't really want to work if I make it volatile.
DM> If it is volatile, the compiler complains.
JC> Three things: what version of STL are you using, what compiler are you
JC> using, and what are the errors you get?
GCC. That should about explain it. ;-)
The errors are asking me to find a type::func(...) volatile function which,
obviously, doesn't exist when my variable of type "type" is volatile. i.e.:
volatile queue > IOQueue;
IOQueue.push('c'); // no queue >::push(char) volatile!
So, at the least, I expect that volatile functions are required...
DM> If it isn't volatile, it becomes really funny - I write to the
DM> serial port fine, but reading doesn't always seem to work... if I
DM> don't give it a long enough delay, the "AT" coming back from the
DM> modem (which I see in a line monitor) only is discovered if I give
DM> it a long enough timeout. I'm sure volatile would help here - if I
DM> could figure out what I was doing with it. :-)
JC> That might depend. Assuming that you're working with a device driver
JC> for the serial port rather than driving the hardware directly yourself
JC> the data may be sitting in the device driver's queue for a while. If
Yeah, that was it - I found that one a few hours later. Had to drop my read
to 1 character at a time unless I know there is more waiting.
DM> Leaving it non-volatile and then removing the thread/queue for reading
DM> may work.
JC> If you don't have _some_ queueing (either in the device driver, or
JC> your driver, if you're driving the hardware directly) you're almost
JC> certain to lose characters if you don't have a queue on the input.
As I said, I use the device driver. I know SIO has a 4k buffer for each com
port - although I'm unsure if it dynamically "splits" to whatever is needed
for each buffer, or if that's 4k for each read and write queue on each port.
DM> However, I'm suspicious that the write queue may not work
DM> in stress situations (i.e., trying to send a file).
JC> Writing is generally less difficult than reading, unless you work with
JC> a file transfer protocol that has a timeout. Otherwise the worst that
If I get a "bad value," I can clear all the buffers - my own with a clear(),
and the device driver's with a DosDevIOCtl call.
JC> can generally happen is that you reduce the throughput of the port.
This would generally be a bad thing, too. ;-)
JC> immediately. However, the same general rule holds true: if you don't
JC> read characters quickly enough, you'll end up completely losing
JC> characters.
Which is why I wanted the "infinite" read buffers.
Actually, I now have the thing working - just without the infinite buffers.
I've got my own queue class that is thread-safe (I think), complete with
semaphores. (Well, semaphore. One per object.) It seems to work so far.
I'm just adding the rest of the code needed (i.e., setting baud rates,
DTR/RTS, checking values, etc) for the class itself. The one thing I dislike
somewhat is that I'm going to have to make my events public... so that the
caller can use multiple-wait (mux) calls to wait on read, write, and, say, a
keyboard thread, or any other thread. I could "demand" (via interface
restrictions) that the user of this class was its own thread, but threads
have costs, too... ah well, the joys of design. :-)
Thanks, Jerry.
... I am Homer of Borg. Prepare to be . . . Oooooh, Donuts!
--- FastEcho 1.46
---------------
* Origin: House of Fire BBS - Toronto - (416)601-0085 - v.34 (1:250/536)
|