Holy cow, I wrote a book!
Microsoft's telephone department takes security very seriously.
Your voicemail password must be at least eight digits long.
By comparison, the password for my ATM card is only four digits long.
Because voicemail is that important, I guess.
(Yes, I know about two-factor authentication.
I'm writing this only half-jokingly.)
Why have a conversation when you can dialogue?
I think this is minimal work,
but do others care?
If they don't, then this is one for the ideas that failed bin.
If they do, well let's dialogue...
No need to talk when you can dialogue.
This year, I was woefully unprepared for the annual
Chilly Hilly ride,
not having gotten on my bicycle for the entire month of February.
And I paid dearly for this lack of preparation,
conking out and ending up walking up some of the last few hills.
I rode with a few other people, but I quickly ended up lagging
They would sometimes stop to let me catch up,
but I told them not to bother and just go at their own pace.
At one point, I ran over a nail and lost precious time to a flat tire.
(I took the flat tire as an opportunity to take my midpoint break,
since it occurred just a half mile or so from the cider stop.)
After patching the flat, I caught up to the rest of the group at the
cider stop, where they were nearly ready to resume the ride.
We left the cider stop together, but I quickly fell behind.
I rolled into the finish as the rest of the group finished up their chili
(a traditional post-ride snack),
so we all headed out directly to the ferry.
(Basically, I used their break time as my opportunity to catch up.)
We were just in time for
the 1:10 run, but we were too far back in line and they stopped
accepting riders just as we reached the front.
I guess I had time to have some chili after all,
but by this point I didn't want to lose my place in line.
My record against Chilly Hilly is now even at
2 wins, 2 losses.
Ferry trivia: Even though there was room for more bicycles on the
ferry, they wouldn't accept any more.
This wasn't because they were being mean.
They were following safety rules:
While the limiting factor in how many cars they will allow on the
ferry is the amount of space on the ferry deck,
the limiting factor in how many bicycles they will accept on the ferry
is the number of life jackets they have.
Nobody would know:
Right near the start, a wine store advertised that it was offering
Don't just lubricate your bicycle; lubricate yourself!
One of my friends who was riding by himself noted
"I saw that sign and thought to myself,
you know, I could just go in there, drink wine for three hours,
then tootle back to the ferry for the return trip, and nobody would know."
I wonder if anybody actually did that.
Chilly Hilly trivia:
There were 6028 riders this year,
a huge increase from the 3585 riders last year.
Are you sick of all these little blurbs yet?
Photos of the ferry ride from the Seattle P-I.
The Kitsap Sun link above also has pictures of the ride itself.
kokorozashi wants to know what the rules are which govern
when the second parameter to ShowWindow is overridden
by the STARTF_USESHOWWINDOW flag.
The guiding principle is that the parameter is ignored if
the window manager thinks that the window you're creating
is the application's main window.
The details behind the implementation of this principle
change over time,
so everything from here down is implementation detail
and should not be relied upon.
I'm providing it merely to satisfy your curiosity.
do not rely on information in the second half of this
article because it can and will change.
In fact, just to emphasize the point, I'm going to give
the rules as they once were,
not as they are today.
So anybody who relies on this information is relying
on implementation details of Windows which are no longer
The window manager heuristics for determining
whether the second parameter to ShowWindow
should be overridden were once as follows:
Rule zero: If the override has already been used,
then don't use it again.
Rule one: The easy case.
If the second parameter was
then the application was explicitly permitting the
second parameter to ShowWindow to be
overridden by the STARTF_USESHOWWINDOW
flag, so let it happen.
Rule two: Check the following properties.
Let's look at these heuristics one at a time.
First, the STARTF_USESHOWWINDOW flag needed
to be set:
If it wasn't, then there wasn't anything
to override with.
Next, the window needed to be top-level (not a child window).
Because a child window clearly is not the application's
The window also must not have been owned.
An owned window is not the main window
(the owner would be a much better candidate),
and besides, it would be bad to have minimized or hidden
an owned window,
since that would have left the owner sitting around for
apparently no reason.
Even worse if the window being created was intended
to be modal to the owner:
You would have had a disabled window on the screen,
and the window you needed to close in order
to get that window enabled again was hidden!
Another rule was that the window had to have a caption.
This made it less likely that
splash screens and other incidental windows
would be misdetected as the application's main window.
System-modal windows were also excluded,
because you didn't want system-critical
error messages to be mistaken
for the application's main window.
(Especially if the action was SW_HIDE!)
The second parameter to ShowWindow had
to be one of the special values
These values were most likely to be passed by applications
which were not particular about how the window was shown.
They would be comparatively unlikely to be upset that
their attempt to show the window was overridden.
Once a window was identified as a likely main window
(either by explicitly saying so via SW_SHOWDEFAULT
or implicitly via the heuristics),
the second parameter to
ShowWindow was ignored and replaced with the
value specified by STARTF_USESHOWWINDOW.
There was some other fiddling that happened,
but they aren't really
important to the topic at hand, so I'll ignore them.
Again, I reiterate that this information is provided merely
to satisfy your curiosity and must not be relied upon
by applications, since the heuristics may be tweaked in
future versions of Windows.
If you want the STARTF_USESHOWWINDOW flag
to have an effect on your program,
just pass SW_SHOWDEFAULT to ShowWindow.
That's the value that says,
"No really, I'm asking for it.
Lemme have it."
Oscar Night is a few weeks away, but
when you settle in to watch the show with your bowl of popcorn,
please be aware that inhaling deeply from the
fumes of a freshly-opened bag of microwave popcorn is
not the greatest decision you can make from a health standpoint.
(Then again, you probably ought to reconsider
eating microwave popcorn in the first place,
but let's leave that aside.)
A disease informally known as popcorn lung afflicts
people who work in popcorn factories and has been known since 2002.
But in 2007,
doctor diagnosed the first case of popcorn lung in an end-user.
The risk is not from eating the popcorn but from breathing it.
"This patient described enjoying the smell so much he was
actually inhaling the steam."
The best part of the article was when the patient was asked,
"Are you around a lot of popcorn?"
"I am popcorn."
Update: Oscar Night is
not actually this weekend.
That's what happens when you schedule your blog entries over a year
in advance and have to guess when Oscar Night is coming.
We saw fibers a long time ago when I looked at how you can
use fibers as a form of coroutines to simplify the writing of
A fiber is a handy tool,
but it's a tool with very sharp edges.
fibers are promiscuous with threads,
you have to be careful when running code that cares
about what thread it is running on,
because that code may discover that its thread
changed out from under it.
For example, critical sections and mutexes remember which thread
If you enter a critical section on a fiber,
and then you unschedule the fiber,
then reschedule it onto a different thread,
and then you leave the critical section,
your critical section will end up corrupted because
you broke the rule that says that a critical section
must be exited on the same thread that entered it.
Actually, you were already in bad shape once you unscheduled
the fiber while it owned a resource:
An unscheduled fiber cannot release the resource.
Unscheduling a fiber is like
suspending a thread:
Anybody who later waits for that fiber to do anything will be
waiting for an awful long time,
because the fiber isn't running at all.
The difference, though, is that the fiber is unscheduled at controlled
points in its execution, so you at least have a chance at suspending
it at a safe time if you understand what the fiber is doing.
For example, suppose you enter a critical section on a fiber,
and then unschedule the fiber.
Some time later, a thread (either running as a plain thread
or a thread which is hosting a fiber)
tries to enter the critical section.
One of two things can happen:
if you use an object which has thread affinity on a fiber,
you are pretty much committed to keeping that fiber on that
thread until the affinity is broken.
This affinity can be subtle,
because most code was not written with fibers in mind.
Any code which calls TlsGetValue has thread
because thread local storage is a per-thread value,
not a per-fiber value.
(This also applies to moral equivalents to TlsGetValue,
like code which calls GetCurrentThreadId and uses it as
a lookup key in a table.)
You need to use FlsGetValue to get values
which follow fibers around.
But on the other hand, if the code is not running on a fiber,
then you can't call FlsGetValue since there is no
fiber to retrieve the value from.
This dichotomy means that it's very hard if not impossible
to write code that is both thread-safe and fiber-aware
if it needs to store data externally on a per-thread/fiber basis.
Even if you manage to detect whether you are running on a thread or
a fiber and call the appropriate function,
if somebody calls ConvertThreadToFiber or
then the correct location for storing your data changed
behind your back.
If you are calling into code that you do not yourself control,
then in the absence of documentation to the contrary,
you don't really have enough information to know whether
the function is safe to call on a fiber.
For example, C runtime functions like
have thread affinity (even though there's nothing obviously
threadlike about comparing strings)
because they rely on the current thread's locale.
(similar to the bottom line from
You have to understand the code that runs on your fiber,
or you may end up accidentally stabbing yourself in the eyeball.
Structured exception handling is fiber-safe since it
is stack-based rather than thread-based.
Note, however, that when you call ConvertThreadToFiber,
any active structured exception handling frames on the thread
become part of the fiber.
Wow, it's been a long time since
my last rant against food products that are offenses against nature.
Today's rant is against
a product which
Kraft launched in April 2008.
Bagel-fuls (note the hyphen and the lowercase "f")
are a dense, doughy material formed into a log shape,
with a cream cheese filling.
Think of them as
but with cream cheese instead of a sugar
cream filling, and with a dense, doughy substance instead of
whatever alien material it is they make Twinkies out of.
The great thing about this product is that it is an attempt
by Kraft to learn its lesson from a previous failed bagel-like product:
Philadelphia To Go bagel,
a package consisting of a frozen bagel,
a one-ounce tub of cream cheese, and a plastic knife.
For people who are unable to remember where they kept their
cream cheese (hint: the refrigerator) and knives (hint: cutlery drawer).
Apparently, Kraft's conclusion was not that the product failed
because it was too stupid, but rather that it failed because
it was not stupid enough.
What happens to the fibers which ran on a thread when the thread exits?
Are all the fibers destroyed?
No, only the currently-executing fiber is destroyed.
Fibers running on other threads and fibers which are not
running on any thread at all are not affected.
Fibers do not have thread affinity (when not running),
and they do not remember what threads they have been run on.
Indeed, one of the features of fibers is that you can switch away
from a fiber on one thread,
then switch to that same fiber on another thread,
and that fiber will resume execution on the new thread.
Fibers are the social butterflies of scheduling:
They will hang out on any thread that invites them to run.
Once one thread deschedules a fiber,
the fiber loses any affinity for the thread and is perfectly
happy to hang out on any other thread.
Or on the original thread,
if the original thread comes crawling back begging for another chance.
You can run a fiber on any thread you want,
provided you don't run it on two threads at once.
(Well, and of course, you have to have prepared the thread for
fiber execution by calling ConvertThreadToFiber.)
Next time, some additional musing about fibers.
Be careful not to
confuse the two.
Since we're sharing:
During a conversation in German, I talked about
seeing Unfall (accident) instead of Abfall
(garbage) on the street.
To my credit, I immediately corrected my error.
To my discredit, the error was made at the state finals of
a German language contest.
Some time ago,
asked (and answered),
How the @#%&*! does CBS_SORT choose to sort it all out?
One detail in his answer is that the sorting algorithm used
is basically CompareString,
with special treatment for the left square bracket U+005B.
Why is the left square bracket so special?
It goes back to the LB_DIR message
(which is in turn used by
and related functions).
If you ask for drives to be added to the list or combo box,
they are added in the form [-X-], where X
is the drive letter.
The left square bracket is special-cased so that the drive
letters sort to the top of the list.
Of course, LB_DIR and related functions and messages
are pretty old-school nowadays,
but the code for them is still around,
so the sort function still needs to worry about them.