Sunday, September 19, 2004

"Who The Hell Is Elaine Stritch"

This is a great recipe -- I just made it. The culinarilly-inclined among you (Ted) may want to give it a shot. Takes about half an hour to prepare; cost like $15, serves two. For $7 more you could make enough for four, I'd wager.

Watching the Emmys for some reason. Tony Kushner, you are the original punk rocker.

I just solved this stupid synchronization problem that I'd been poking at all weekend and not getting. I say it's stupid because it looks obvious now that I've solved it, but, you know... ugh. And of course I'm going to explain because that's one of the things I like to do. So.

A semaphore is a synchronization primitive (well, it's not necessarily a primitive, but...) consisting of a condition variable and a counter. You can "wait on the semaphore" by attempting to decrement the value of the counter. If it's greater than zero when you do this, the counter gets decremented and the call returns immediately; if it's zero, your thread goes to sleep until another thread "posts the semaphore," incrementing the value of the counter, at which point your thread wakes up, decrements it, and the call returns.

Many semaphore implementations provide, in addition to the "wait" function, a "trywait" function, in which you merely check the value of the semaphore, and if it's zero, instead of sleeping, you just inform the calling thread that it would have slept. If it's not zero, you do what the normal wait function does, which is decrement the value of the counter and return. My semaphore implementation provides this function.

Here's what happened: I wanted to wait for an item to be added to this queue (the queue's embedded semaphore would get posted when this happened). I didn't want to wait forever, though, so I did a trywait on the queue's semaphore, and if it came back false, indicating that the value of the counter was zero, I would wait for a while to see if somebody added something to the queue -- and if they did, grab it and return it, otherwise just return NULL. Here's the problem: I'd do the trywait, it would come back false, so I'd sleep for a while, get woken up by somebody adding to the queue, grab the value, but hold on a sec -- the semaphore's counter never got decremented, because the trywait came back false initially and we never decremented when we got woken up! So the next person to wait for an item to get added to the list would see that the semaphore's counter was non-zero, decrement it, try to grab something off the list, get NULL, and, well... It showed up in my program as the server pinging the client over and over without waiting for the timeout period to pass.

Why do I post these boring explanations of boring stuff? Well, because it's not boring, fuckers -- it's awesome! It's totally a mind-blow the extent to which code can seem like this gaseous, chaotic stuff until you resolve a bug and all of a sudden it all coalesces into a beautiful, mechanically glorious whole. Three worlds, guys. Three worlds.

Starting to work on documentation; DocBook is real fun to work with, but the docbook2texinfo converter is super frustrating because it insists on naming your fucking info document with a normalized string it generates based on a bunch of mystery factors that I can't control. Like, for example, I can't make it produce 'gzochi-server.info' out of 'gzochi-server-manual.docbook.xml'. The best I can seem to do is 'gzochi_server_manual.info'. You hear that Steve Cheng? Insane. And don't get me started on how retarded automake can be when it comes to dynamically-generated documentation.

I didn't do anything this weekend.

No comments: