Tombstone
ZenerdOverlapppedServer
May 2001 – Jun 2001 · age 19
What it was
A TCP server skeleton built to learn how to hold many connections without a thread per client, written in C++ against Winsock 2's overlapped I/O and shaped closely on the Platform SDK sample. The name has three p's throughout, and it is kept that way. Each client got a record holding its socket, an 8,124-byte buffer, an overlapped structure, byte counters and a phase field. An accept loop posted the first receive for each new client and rang slot 0 of a shared event array as a doorbell. A worker thread slept on all 64 events in one call, woke with an index, collected the result, compacted the arrays when a socket closed, printed whatever arrived to the console, and posted the next receive. The send and close paths were stubs. The protocol was going to be decided later, and later never came.
Wins, for the age
- At nineteen, Jeff made asynchronous, completion-based I/O click: post a receive, sleep on every outstanding operation at once, wake with an index. Windows NT's completion ports had long since packaged this; this primate learned the machinery underneath them by hand.
- Kept slot 0 as a doorbell so the worker would wake and re-enter its wait with each new socket included, and understood why it had to be there.
- Gave each connection an explicit state record with a phase, the shape every async server still has under the hood.
- Wrapped start, stop and port in locked accessors so a future UI thread could control the server safely. Thinking about the next thread before it existed.
What it taught
- The 64-handle ceiling is real, and it is the whole reason completion ports exist.
- A server without a wire protocol is not a server, and "decide later" for the byte format tends to mean never.
- The first race shipped unnoticed: a shared client count written under the lock and read without it by the other thread. Anything shared across threads should be verified, not eyeballed.
- A lock with a timeout whose result is ignored is not a lock. Every one here proceeded unlocked on timeout.
- Buffers need lengths. Streaming received bytes to the console with no terminator read past the end whenever a client filled the buffer.
Genealogy
Ancestors: none on record. A study piece, built from the platform's own sample. Descendants: Async Serialization: asynchronous sockets with an actual protocol on top, a year later.
Epitaph
Here lies ZenerdOverlapppedServer, spelled with one p too many and finished with one protocol too few.