May, 2009

  • The Old New Thing

    If an event is signaled more than once, are they delivered in the order in which they were signaled?


    A customer asked the following question:

    Is it guaranteed that the events when signaled multiple times on an event object are delivered in the order in which they were signaled?

    For example, a thread is waiting on the event handle and performs some operation each time it is signaled. The ordering of those operations should be in the same order in which the event is signaled. Do events provide this guarantee? In case it matters, we're using an auto-reset event. We're finding issues when the system is under heavy load.

    This question is confusing because events don't "remember" who signaled them. When an event is signaled, then a waiting thread is released. The waiting thread doesn't know "who" did it; there is no context associated with an event. So the answer is, "Sure, whatever, it comes in the order they were signaled, if that's how you want to think about it. If you want to think about it in reverse order, then sure, they come in reverse order. They come in whatever order you want since there's no way you can detect what order they arrived in, since they are identical."

    You and your friend enter the museum at the same time. The museum attendance person clicks the number counter twice. "Was that first click for me or for my friend?" Who cares? All that got recorded is two clicks. There's nothing in the clicks that associates each one with you or your friend.

    When asked for clarification, the customer explained:

    We have a producer process that signals the waiting thread when certain 'events' occur. The service maintains a single list of context structures for each of these 'events' and then signals the waiting thread to tell it to wake up and take some action based on the associated context. When the client wakes up, it calls back into the producer process to retrieve the details of the event that woke it up. We want to know whether the thread, when it wakes up, will receive those events in the same order they were generated.

    This explanation makes clear that the issue is not the event at all. The issue is the order in which the context structures are added to the list. We have this:

    Thread A:
    Add context to list in some manner
    Signal event
    Thread B:
    Add context to list in some manner
    Signal event
    Waiting thread:
    Wait for event
    Retrieve context from list in some manner
    Do something with context

    The question boils down to "If thread A adds its context and then signals the event, and simultaneously thread B adds its context and signals the event, then when the waiting thread wakes up, is it guaranteed that the waiting thread will retrieve thread A's context first?"

    The answer is "Well, it depends on how you added the context to the list and how you retrieved it." If the race between thread A's "Add context to list in some manner" and thread B's "Add context to list in some manner" is won by thread A, and the waiting thread retrieves the context FIFO, then it will get thread A's context. But the event has nothing to do with it. The race condition took place before the event was signaled.

    The answer to the question is of no real value, however, because this design pattern is flawed from the start. Events are not counted. They have only two states: Signaled and not signaled. Consider the situation where three events are raised in rapid succession.

    Thread A:
    Add context to list in some manner
    Signal event
    Waiting thread:
    Wait for event completes; event returns to unsignaled
    Retrieve context
    Thread A:
    Add context to list in some manner
    Signal event
    Add context to list in some manner
    Signal event (has no effect since event is already signaled)
    Waiting thread:
    Do something with first context
    Wait for event (completes immediately since event is already signaled)
    Event returns to unsignaled
    Retrieve context (gets second context)
    Do something with second context
    Wait for event (waits since event is not signaled)

    Congratulations, you just lost an event signal because setting an event that is already set is a no-op.

    If you need the number of wakes to equal the number of signals, then use a semaphore. That's what it's for.

    In response to this explanation, the customer simply wrote back, "Semaphores worked. Thanks."

  • The Old New Thing

    First, try reading the error message: Episode 1


    Quite some time ago, a customer had forgotten that they were using an evaluation edition of Windows, and they were awakened one morning with the following error message:

    The evaluation period for this installation of Windows has expired. This system will shut down in 1 hour. To restore access to this installation of Windows, please upgrade this installation using a licensed distribution of this product.

    The customer submitted an urgent request for assistance. "Please advise how we can get this machine working again. We need it to run a demo for a major client later this week."

    In the customer's panic, they forgot to read the actual error message, which tells them what they need to do:

    To restore access to this installation of Windows, please upgrade this installation using a licensed distribution of this product.

    In other words, get a non-evaluation edition of Windows and perform an upgrade install. (Kick it off as soon as you finish booting up so you don't get the rug yanked out from under you if you dawdle and take more than an hour to get through setup.) This will preserve all your existing data while upgrading it from an evaluation edition to the real thing.

    Pre-emptive snarky comment: "The existence of evaluation editions with expiration dates proves that Microsoft is evil."

  • The Old New Thing

    Signs that your new building was originally designed for another purpose: Rest rooms


    There's always a settling-in period when you move offices, learning where things are, like the rest room, the kitchen, the printer room, the cafeteria, the locker room, your boss...

    My new office is conveniently close to the rest room. Actually, this building is laid out kind of weird. There are two sets of rest rooms within a short distance of each other, on opposite sides of a stairwell. You can wave hello from one to the other and have a conversation. My office is nearly halfway between them. But I can use only one of them.

    On the south side, there are two rest rooms, a men's room and a women's room. On the north side, there is a women's rest room and a storage closet.

    Clearly the people who originally commissioned this building were not a tech company with a sterotypical gender balance.

    Bonus rest room imbalance: There is a men's room on the upper floor near some conference rooms. It has no urinals, only stalls. This was clearly a former women's room that merely has a new sign on the door. Whenever I use it, I have this brief moment of panic when it appears that I went into the wrong rest room by mistake.

    Double bonus rest room quirk: There is a rest room just off a large gathering area. It is a unisex rest room which serves only one person at a time, and it is huge—maybe two thirds the size of an office. Last year, a friend of mine flew up to Redmond to interview with Microsoft. (It was for a group I have no connection to, so there's no conflict of interest, thanks for asking.) Her inbound flight was delayed, so she arrived at Microsoft campus with only a half hour to spare before her first interview. I took her to the luxury rest room, which gave her plenty of space to change from her travel clothes to her interview clothes, freshen up, and make it to her first interview.

  • The Old New Thing

    Just letting you know I had to reboot my telephone


    Shortly after my group got switched over to new fancy-dancy IP phones, one of my colleagues sent me email to say "This morning, when I picked up the phone, I kept getting a 'URL not allowed' error. I fixed it by rebooting my phone."

    So this is what the world has come to.

    Bonus chatter: As many readers surmised, these "new" IP phones arrived over a year ago. On the other hand, I never did get to learn all the features of the device before it was replaced with a different model of IP phone. Progress.

  • The Old New Thing

    How do I know whether a window message was processed?


    Commenter Skeets Norquist asks how to tell whether the original window procedure processed a message when you use CallWindowProc to call the original window procedure. "CallWindowProc() always seems to return an LRESULT of 0."

    No, actually, CallWindowProc returns whatever the window procedure did. If the window procedure returned zero, then CallWindowProc returns zero. If the window procedure returned 5, then CallWindowProc returns 5.

    Anyway, back to the original question. You actually know the answer, if you think about it the right way, and there are many right ways of thinking about it.

    Technique number 1: Reading the contract from the other side.

    How do you know whether the original window procedure handled the message? Well, how does the window manager know that you handled the message? When you subclass a window, you are simultaneously implementing both sides of the message-handling contract. The window manager calls your window procedure, which is the recipient side of the contract. You, in turn, call the original window procedure, acting as the sending side of the contract. Therefore, the way you know whether the message was handled by the original window procedure is the same way the window manager knows that you handled the message yourself. For example, if the message is WM_SETCURSOR, then the window procedure returns TRUE to halt further processing or FALSE to continue. This statement applies both to your window procedure as well as the original window procedure, since they're both window procedures!

    Technique number 2: Use the golden rule.

    This is a very common technique for answering questions like "How do I make «something somebody else has written» «behave in some way»?" If you want to look for a way to somebody else behave in some way, you mentally turn the tables: How would somebody else make me behave in that way?

    Here's a specific example: "What message do I send a window to ask if it contains an unsaved document?" Well, let's turn it around: What message would somebody send to you to ask if you contained an unsaved document?

    "I don't have a message for that. It's just a boolean flag in my CDocument class. There's no message for retrieving it."

    Well, if you don't have a message for retrieving the "dirty" flag from your own document, then clearly there is no generic message for it. Because if there were, you'd have implemented it!

    Now let's transfer this to the message handling case. You write a window procedure. How do you indicate that you processed the message? Whatever method you use as a window procedure to indicate that you processed the message is the same method you use as the caller of CallWindowProc to tell whether the message was handled.

    Technique number 3: How do you know whether the base class performed the operation when you override a method in C++? (Or C# or Java or whatever object-oriented language you prefer.)

    Subclassing a window is like subclassing a C++ class: Method calls are given to your class first, and you can decide whether to handle it entirely yourself, whether to pass it through to the base class unchanged, or to combine the two (calling the base class and also performing some operation on your own). So let's take the message handling question and turn it into a method override question: If you override a method and then call the base class, how do you know whether the base class implemented the method?

    That's right, and that's how you tell whether the original window procedure handled a message.

    (The misssing paragraph is, "Well, it depends on the method and what the specification is for how classes should respond to the method.")

    Look at the problem three different ways, but it's all the same answer: You tell whether a window procedure processed a message by comparing the actual behavior against the specification.

    Now, in practice, window messages are almost all of the form "You must process the message. If you don't want to do anything special, then pass it to DefWindowProc and let it do the default processing and return an appropriate value." In those cases, the answer to the question of how to tell whether the message was handled is much easier: The fact that it returned means that the message was handled.

    One might even say that the messages like WM_SETCURSOR fall into the same category of "The fact that it returned means that the message was handled." Because even if the original window procedure returned FALSE to indicate that it wants processing to continue, that is in a sense how it handled the message. It handled the message by saying, "I am handling this message by telling you that I want you to continue processing."

  • The Old New Thing

    Windows Vista User Experience Guidelines is online and downloadable


    Get it before it's obsolete. The Windows Vista User Experience Guidelines document is available in PDF format.

  • The Old New Thing

    Imagine our luck when we found one of the fancy conference rooms available for our meeting


    Some time ago, the group I was a member of was looking for a conference room in which to hold their weekly team status meeting. The group leader went to the so you want to book a conference room for your weekly meeting internal Web site and, hey wow, there was a slot available in one of the fancy conference rooms for Tuesdays at ten in the morning.

    Not all conference rooms are created equal. Most of them are pretty utilitarian in nature with a central table, standard-issue chairs, a speaker phone, a whiteboard against one wall, all the stuff you need for a meeting but nothing particularly noteworthy. But in this particular building were three "fancy" conference rooms right off the lobby with warm wood panelling, a giant flat-screen monitor against one wall, floor-to-ceiling windows on another wall up against the neatly manicured lawn. (I bet these conference rooms were created specifically to impress visitors.) Naturally, these "fancy" conference rooms are snapped up first, and when you try to book a meeting, you nearly always have only the boring rooms to choose from.

    "Awesome, we got one of the fancy conference rooms," we thought to ourselves, and we congratulated ourselves on our good fortune.

    And then we held our first meeting in the conference room.

    The meeting went well at first, but after a few minutes, the roar of landscaping equipment made conversation difficult.

    Remember that neatly manicured lawn right outside the window? That lawn doesn't trim itself by magic. It requires a landscaping department to keep the lawn looking neat and green and in good health. And they do that work on—you guessed it—Tuesdays at ten in the morning.

    It wasn't long before we moved our meeting to one of the boring conference rooms.

  • The Old New Thing

    Parents billed when kids miss school: Pay for play


    The Scotts Valley school system is asking parents to compensate the district when they take their kids out of school to go on vacation. Adds a new wrinkle to the phrase "pay for play".

    I remember the days when we were taught the difference between the things you must do (obligations, responsibilities) and the things you want to do.

  • The Old New Thing

    Creating shortcuts in the same folder as the target isn't as stupid as you may think


    Commenter Mihai wonders, "Why would I want to keep the original file and the link in the same folder?"

    Dragging a file, and in particular right-dragging a file, is not easy for all people. There are people with poor dexterity who have trouble with dragging; for them, right-dragging would be even worse. But even people with normal levels of dexterity have problems with dragging: Just put them in front of a Tablet PC. On a Tablet PC dragging with the fingertip can get tricky because your hand obscures the drag target, and most people don't have very pointy fingers, so the precision of the drop is pretty poor.

    There's another group of users, much larger than Tablet PC users, which have trouble with drag and drop, and you are probably one of them: Laptop users with touchpads. Dragging with a touchpad is a very tricky proposition, particularly if you are dragging a long distance that exceeds the size of your touchpad. If you're really clever, you might be able to multitouch the touchpad and let the second finger continue the drag, but at least in my experience this is not a particularly reliable mechanism for dragging long distances. Even if the mouse motion is continuous, you often get a spurious mouse-up event, which ends the drag prematurely.

    For users for whom dragging is difficult, it's much easier to create a shortcut in the same folder, and then move it to its final destination.

  • The Old New Thing

    People become more trustworthy the more you trust them


    My faith in humanity goes up when I see an unattended self-service stand where customers are trusted to pay for what they take. It works because the system is open to public view, and any passer-by (or even just a poster of a pair of eyes) can spot the cheater. (Then again, it takes only a tiny percentage of cheaters to ruin it for everyone.)

    I remember reading a story on self-checkout devices which said that product theft actually went down after the devices were installed. Apparently the customers were more trustworthy than the employees when it came to retail theft. People will rise to the occasion and be trustworthy because you expect them to be. (I'm told that schoolteachers have known this trick for years: If you make it clear to students that you expect more from them, they will generally rise to the challenge.)

    Fortunately, in my experience at Microsoft, I've seen more metrics + common sense than the pure metrics approach. For example, during the approach to a project milestone, management was watching the bug count very closely, but also understood that the raw numbers were just an approximation of the situation. After all, some bugs are easier to fix than others. A developer's bug count might not go down for a few days because he's working on a complicated bug. Another developer may have a relatively high bug count, but they're all simple bugs that can be taken care of relatively easily. Neither developer was told to "get those numbers under control" (and therefore were not tempted to manipulate the metrics). Indeed, management often chooses to redistribute some of the bugs (when possible) so that the workload is evened out.

    Mark (The other Mark)'s middle ground is also employed. During a bug bash a few years ago, management set the ground rules for the event. There were some prizes to be awarded, but they also reminded participants that the goal of the event was to find useful, relevant bugs. They also reminded participants that the bugs filed should have value: Instead of reporting ten variations on the same underlying bug, file one bug that covers all the variations. It turns out that the bug bash indeed had a low incidence of "garbage bugs" that were filed for the purpose of gaming the metrics.

    All they had to do was ask.

Page 2 of 3 (29 items) 123