On Tue, Sep 8, 2009 at 11:08 AM, Gwynne Raskind
<email@hidden> wrote:
On Sep 8, 2009, at 1:33 PM, Kevin Van Vechten wrote:
I believe the "????" is the result of writing (int)-1 to stdout.
Actually it's much worse. I had used calloc to allocate the context, which had the write fd. I had written -1 to "stdin" (0 is stdin right?)
Writing to stdin causes the console to barf up ?'s ? My program is wrong, but that's interesting behavior all the same.
You're right, stdin is file descriptor zero, which is where the (int)-1 is being written to causing the "????".
I don't know this for certain, but I suspect there's nothing unusual about this behavior of writing to stdin:
For a program run from a terminal, ssh session, etc., stdin, as well as stdout and stderr, is a tty - or more exactly, a pty. If you look look into how pseudo-terminals are used, especially the login_tty() function, you find that the pty slave fd is dup2()d to stdin, stdout, and stderr. This fd was, in turn, opened with O_RDWR. The result is that, in your program, you're reading from and writing to the same descriptor regardless of which stream you use. Therefore, writing to stdin is exactly the same as writing to stdout and stderr, as long as no shell redirections or pipes are in place (more exactly, as long as isatty(STDIN_FILENO) returns 1).
So, why four question marks? The hexadecimal value of (int)-1 is 0xFFFFFFFF (two's complement signed integer). Write that to a byte stream (such as a pseudo terminal), and you've output four 0xFF bytes. 0xFF is an illegal character in UTF-8 (the default encoding for Terminal and Xcode) and some other encodings, so whatever your console is, it spits out a "nonprintable character" character. Depending on your font and console, this could be ?, <FF> in inverse video, the question mark in a black diamond, etc.
You can prove it by running this command from Terminal:
/usr/bin/php -r 'fwrite(STDIN, "Hello, world!\n");'
-- Gwynne
Great explanation Gwynne! Thanks to you and Kevin for your assistance.
I'm most impressed by the fact that I've had to write absolutely no explicit locking code through this exercise, but instead have had to only figure out which queues to submit transactions for scheduling purposes.
So libdispatch doesn't get rid of needing to understand synchronization (which no concurrency facility I'm aware of can get one away from) but not having to do anything explicitly with locks has been quite nice.
However, as you can probably tell, I'd almost prefer an actor based lightweight messaging API. Mach messages would be nice perhaps, but my understanding is that use of that low level stuff is just taboo in Mac OS X, as the interfaces are subject to change. Still a lightweight mailbox for sending messages from block to block and having blocks get scheduled on queues based on availability would be a most excellent enhancement to this.
If we could get said facility in C++ with a template with a little type safety embedded, it'd be even better. Bonus points for a streambuf interface so I can send messages to actors with "handle << msg" syntax :-).
Could be quite a fun project to try to do all of this. I can see programs that handle input in different ways, using generic STL algorithms doing "copy" commands to iterators that are plugged into streambufs for message passing between blocks, and writing very little code to do some interestingly concurrent code.
Dave