• The Old New Thing

    Sorry I missed you all this morning


    Sorry to all you PDCers who stopped by the Fundamentals Lounge to see me. The scheduling software that the PDC organizers cooked up is, um, "suboptimal" and listed me for Tuesday 11.30a–2.30p instead of 2.30p–5.30p. During the early afternoon shift, I was actually in the Hands-On Lab. But I'll be in the Lounge on Thursday after my talk all afternoon, really.

    I will try to be in the Lounge on Wednesday, but I may have to take refuge in the Speaker Prep Room to deal with a major last-minute change to my talk.

    Whoa a huge stream of people just flooded in. I'll catch up with you folks later.

  • The Old New Thing

    Annoying renditions of the songs of Elvis


    Jim Nayder of The Annoying Music Show pops by NPR studios every so often—hey, guys, if you changed the locks, this might stop him—whereupon he tortures the general public with musical offenses that should be outlawed by the Geneva Conventions. Most recently, he offered a series of reinterpretations of the works of Elvis Presley. What's really scary is that the songs presented in the segment are among the less awful offerings. For genuine musical pain, check out Love Me Tender [WMV] [Real] as performed by "Sweden's Singin' Sensation" Eilert Pilarm. (Quick tip: "Lyssna" is Swedish for "listen.")

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Why is there no all-encompassing superset version of Windows?


    Sometimes, I am asked why there is no single version of Windows that contains everything. Instead, as you move up the ladder, say, from Windows XP Professional to Windows Server 2003, you gain server features and lose workstation features. Why lose features when you add others?

    Because it turns out no actual customer wants to keep the workstation features on their servers. Only developers want to have this "all-encompassing" version of Windows, and making it available to them would result in developers testing their programs on a version of Windows no actual customer owns.

    I think one of my colleagues who works in security support explained it best:

    When customers ask why their server has Internet Explorer, NetMeeting, Media Player, Games, Instant Messenger, etc., installed by default, it's hard for the support folks to come up with a good answer. Many customers view each additional installed component as additional risk, and want their servers to have the least possible amount of stuff installed.

    If you're the CIO of a bank, the thought that your servers are capable of playing Quake must give you the heebie-jeebies.

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Richard E. Grant as Dr. Who


    While waiting for the Ninth and Tenth Doctors to reach the States, I was tipped off to some animated Dr. Who episodes on the BBC web site. These are really well done and managed to slake my Doctor cravings for a little while longer.

    In particular, Richard E. Grant's second turn as the somewhat Earth-obsessed Time Lord in Scream of the Shalka is a must-see. The tired frustration of his Doctor is a refreshing change from the more amiable personas he's had in recent incarnations. After saving the Earth (nay, the universe) from certain destruction for over forty years, you kind of can't blame him for being fed up with the whole thing.

    (Second turn as The Doctor? Yup. Richard E. Grant played The Tenth Doctor in Doctor Who and the Curse of the Fatal Death, a spoof produced for the charity organization Comic Relief. I think Rowan Atkinson makes an excellent Doctor, if I may say so myself.)

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Understanding the consequences of WAIT_ABANDONED


    One of the important distinctions between mutexes and the other synchronization objects is that mutexes have owners. If the thread that owns a mutex exits without releasing the mutex, the mutex is automatically released on the thread's behalf.

    But if this happens, you're in big trouble.

    One thing many people gloss over is the WAIT_ABANDONED return value from the synchronization functions such as WaitForSingleObject. They typically treat this as a successful wait, because it does mean that the object was obtained, but it also tells you that the previous owner left the mutex abandoned and that the system had to release it on the owner's behalf.

    Why are you in big trouble when this happens?

    Presumably, you created that mutex to protect multiple threads from accessing a shared object while it is an unstable state. Code enters the mutex, then starts manipulating the object, temporarily making it unstable, but eventually restabilizing it and then releasing the mutex so that the next person can access the object.

    For example, you might have code that manages an anchored doubly-linked list in shared memory that goes like this:

    void MyClass::ReverseList()
     WaitForSingleObject(hMutex, INFINITE);
     int i = 0; // anchor
     do {
      int next = m_items[i].m_next;
      m_items[i].m_next = m_items[i].m_prev;
      m_items[i].m_prev = next;
      i = next;
     } while (i != 0);

    There is nothing particularly exciting going on. Basic stuff, right?

    But what if the program crashes while holding the mutex? (If you believe that your programs are bug-free, consider the possiblity that the program is running over the network and the network goes down, leading to an in-page exception. Or simply that the user went to Task Manager and terminated your program while this function is running.)

    In that case, the mutex is automatically released by the operating system, leaving the linked list in a corrupted state. The next program to claim the mutex will receive WAIT_ABANDONED as the status code. If you ignore that status code, you end up operating on a corrupted linked list. Depending on how that linked list is used, it may result in a resource leak or the system creating an unintended second copy of something, or perhaps even a crash. The unfortunate demise of one program causes other programs to start behaving strangely.

    Then again, the question remains, "What do you do, then, if you get WAIT_ABANDONED?" The answer is, "Good question."

    You might try to repair the corruption, if you keep enough auxiliary information around to recover a consistent state. You might even design your data structures to be transactional, so that the death of a thread manipulating the data structures does not leave them in a corrupted state. Or you might just decide that since things are corrupted, you should throw away everything and start over, losing the state of work in progress, but at least allowing new work to proceed unhindered.

    Or you might simply choose to ignore the error and continue onwards with a corrupt data structure, hoping that whatever went wrong won't result in cascade failures down the line. This is what most people do, though usually without even being aware that they're doing it. And it's really hard to debug the crashes that result from this approach.

    Exercise: Why did we use indices instead of pointers in our linked list data structure?

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Reading the output of a command from batch


    The FOR command has become the batch language's looping construct. If you ask for help via FOR /? you can see all the ways it has become overloaded. For example, you can read the output of a command by using the for command.

    FOR /F "tokens=*" %i IN ('ver') DO echo %i

    The /F switch in conjunction with the single quotation marks indicates that the quoted string is a command to run, whose output is then to be parsed and returned in the specified variable (or variables). The option "tokens=*" says that the entire line should be collected. There are several other options that control the parsing, which I leave you to read on your own.

    The kludgy batch language gets even kludgier. Why is the batch language such a grammatical mess? Backwards compatibility.

    Any change to the batch language cannot break compatibility with the millions of batch programs already in existence. Such batch files are burned onto millions of CDs (you'd be surprised how many commercial programs use batch files, particularly as part of their installation process). They're also run by corporations around the world to get their day-to-day work done. Plus of course the batch files written by people like you and me to do a wide variety of things. Any change to the batch language must keep these batch files running.

    Of course, one could invent a brand new batch language, let's call it Batch² for the sake of discussion, and thereby be rid of the backwards compatibility constraints. But with that decision come different obstacles.

    Suppose you have a 500-line batch file and you want to add one little feature to it, but that new feature is available only in Batch². Does this mean that you have to do a complete rewrite of your batch program into Batch²? Your company spent years tweaking this batch file over the years. (And by "tweaking" I might mean "turning into a plate of spaghetti".) Do you want to take the risk of introducing who-knows-how-many bugs and breaking various obscure features as part of the rewrite into Batch²?

    Suppose you decide to bite the bullet and rewrite. Oh, but Batch² is available only in more recent versions of Windows. Do you tell your customers, "We don't support the older versions of Windows any more"? Or do you bite another bullet and say, "We support only versions of Windows that have Batch²"?

    I'm not saying that it won't happen. (In fact, I'm under the impression that there are already efforts to design a new command console language with an entirely new grammar. Said effort might even be presenting at the PDC in a few days.) I'm just explaining why the classic batch language is such a mess. Welcome to evolution.

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    I won't be signing books but don't let that stop you


    Whereas Eric Carter will be signing his book (co-authored with another Eric) at the PDC. I have no book of my own to sign, but will be happy to sign the Erics' book if you ask me to! You can catch me in the Fundamentals Lounge pretty much the whole time.

    There have been some changes to my talk since I wrote about it last time. The lecture style is gone; the material simply didn't support it. It's just going to be a conventional talk against a series of slides. I sort of painted myself into a corner with my title, Five Things Every Win32 Developer Should Know: If you should know it, then it can't be all that advanced can it? As a result, my talk is really more of a high 200's/low 300's type of talk. But maybe just collecting all these factoids in one place makes it worthy of a 400 rating?

  • The Old New Thing

    Why does the function WSASetLastError exist?


    Why does the function WSASetLastError exist when there is already the perfectly good function SetLastError?

    Actually, you know the answer too, if you sit down and think about it.

    Winsock was originally developed to run on both 16-bit Windows and 32-bit Windows. Notice how the classic Winsock functions are based on window messages for asynchronous notifications. In the 16-bit world, there was no SetLastError function. Therefore, Winsock had to provide its own version for the 16-bit implementation. And since source code compatibility is important, there was a 32-bit version as well. Of course, the 32-bit version looks kind of stupid in retrospect if you aren't aware of the 16-bit version.

  • The Old New Thing

    Declared unsuitable for minors in Australia! Sort of.


    A colleague of mine wrote to let me know

    Your blog is blocked as "adult content" in the internet cafe I'm currently using in Adelaide, South Australia. Other MSDN blogs show up without problem.

    You must have really have spiffed up the content since I left the states!

    Perhaps that should be my new subtitle. "The Old New Thing: Must be 18 or older to enter."

  • The Old New Thing

    Why aren't low-level hooks injected?


    When I described what the HINSTANCE parameter to the SetWindowsHookEx function is for, I neglected to mention why the low-level hooks are not injected.

    But then again, it should be obvious.

    The low-level hooks let you see input as it arrives at the window manager. At this low level of processing, the window manager hasn't yet decided what window will receive the message. After all, that's the whole point of the low-level hook: to filter the input before the window manager does anything with it. "Deciding what window should get the message" counts as "anything". Consequently, it can't inject the call into the destination window's context even if it wanted to. There is no destination window yet!

    So, for lack of a better choice, it uses the context that registered the hook. Of course, all this context-switching does come at a cost. Low-level hooks are consequently very expensive; don't leave them installed when you don't need them.

Page 370 of 458 (4,573 items) «368369370371372»