Errata

Win32 Multithreaded Programming

Errata for Win32 Multithreaded Programming

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
Printed
Page xiii
next-to-last para., last line: changed "Mfc" to "Mcl"

Anonymous    Apr 01, 1998
Printed
Page 3
The second line of the third bullet did read: "...spends a large

faction..."

Now reads:

"...spends a large fraction..."

Anonymous    Jun 01, 2000
Printed
Page 7
The last line of code on the page did read: "PGADGET PFreeGadget =

gpFreeGadgetss;"

Now reads:

"PGADGET PFreeGadget ="gpFreeGadgets;"

Anonymous    Jun 01, 2000
Printed
Page 33
last bullet, line -4: changed "objet" to "object"

Anonymous    Apr 01, 1998
Printed
Page 47-48
The following statement in the last paragarph of this page was

incorrect:

"This technique [using CREATE_SUSPENDED with CreateProcess] is
generally used by a parent process that wants to assign the STDIN
or STDOUT handles for the child process to refer to a pipe or other
kernel object. By creating the process so that the primary thread
is initially suspended, the parent process can safely use the
SetStdHandle function to redirect one or more of the standard input
or output handles for the child process before the primary thread
has a chance to execute."

In fact, by the time the parent process returns from calling CreateProcess,
the handle table for the child process is completely initialized, including
those entries used for stdin, stdout, and stderr. To modify the STD handle(s)
of a child process, the parent process must replace it's own STD handle(s)
using SetStdHandle, launch the child process using CreateProcess and the
bInheritHandles parameter set to TRUE, then restore the parent STD handles
to their original state. Alternatively, the STARTUPINFO field members
hStdInput, hStdOutput, and/or hStdError may be used to setup the STD handles
of a child process that is being started.

This sentence and every sentence that follows to the end of the paragraph
has been deleted. So the last sentence in this paragraph is now "In this
case, the primary thread for a process will not begin exeuting the main or
WinMain function until the parent process has called the ResumeThread
function."

Anonymous    Jan 01, 2000
Printed
Page 75
last item in last table: changed "object" to "objects"

Anonymous    Apr 01, 1998
Printed
Page 84
next-to-last para: changed the last 5 lines, starting with "If a

thread owning a mutex exits..." and continuing on to the end of the
paragraph, to the following:

Note that if a thread owning a mutex exits or is terminated before
releasing the mutex, one of the threads waiting for ownership of that
mutex will return from its wait function with a failure code of
WAIT_ABANDONED_0, or a value between WAIT_ABANDONED_0 and
(WAIT_ABANDONED_0 + nCount-1) for the multiple object wait
functions. That thread is now the owner of the mutex, and must use
ReleaseMutex just as if a return value of WAIT_OBJECT_0 or
(WAIT_OBJECT_0 + nCount-1) had been returned. This means that both the
WaitSucceeded and WaitAbandoned functions presented earlier indicate
you own the mutex and need to release it. Most of the time, an
abandoned mutex is a sign of a bug in the logic of a thread somewhere
and should be asserted so that you can track down the problem as early
as possible.

where the WAIT_ABANDONED items are in CW, "nCount" is in italic CW
both times it appears, and the function names are in Roman itals.

Anonymous    Apr 01, 1998
Printed
Page 84

The third sentence of the second full paragraph on the page now reads:

"If a thread owning a mutex exits or is terminated before releasing the mutex,
one thread waiting for ownership of that mutex will return from its respective
wait function with a failure code of WAIT_ABANDONED_0, or a value between
WAIT_ABANDONED_0 and (WAIT_ABANDONED_0 + nCount - 1) for the multiple object
wait functions."

Anonymous    Jun 01, 2000
Printed
Page 85
reprinted for pagebreak

Anonymous    Apr 01, 1998
Printed
Page 110
Removed the * footnote from the last paragraph on page 110 that refers

the reader to the editorial note (the sentence that begins "In fact, since
the MapViewOfFile function increases the usage counts..."). No text has been
changed in the paragraph preceding the code listing - just the footnote has
been removed.

After the listing on page 110 (which is fine as-is), this new paragraph has
been added:

"While closing the file mapping handle immediately after calling
MapViewOfFile is valid when performing memory-mapped file I/O, this
technique should not be used when using a file mapping object for
shared memory purposes. In the shared-memory scenario, two or more
processes have agreed on the name for the mapping object. If one
application closes the mapping object after calling MapViewOfFile
before the cooperating application has a chance to call
CreateFileMapping or OpenFileMapping, the named mapping object may
no longer exist (or at least, may no longer be identifiable by the
agreed upon name), and the two applications will not achieve shared
memory as desired. For this reason, the mapping object handle
should not be closed until you no longer have any need to use the
shared memory."

Anonymous    Jan 01, 2000
Printed
Page 111-112
Replaced the code listing in Example 5-1 (ShareStr.c) with the

following code. This source, which demonstrates using a mapping object for
shared memory, follows the recommendation made in the new paragraph on page
110.

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define MAX_STRING_SIZE 256
#define FILE_MAPPING_NAME __TEXT("ShareStrSharedMemory")
#define INITIAL_STRING __TEXT("(nothing yet)")

int main( int argc, char *argv[]) {
HANDLE hMapping;
LPTSTR lpSharedString;
TCHAR szLocalString[MAX_STRING_SIZE];
BOOL bCreated;

// create a named file mapping as shared memory...
hMapping = CreateFileMapping( (HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0,
MAX_STRING_SIZE, FILE_MAPPING_NAME);
if (hMapping != NULL) {
if (GetLastError() == ERROR_ALREADY_EXISTS) {
bCreated = FALSE;
printf("Opened preexisting file mapping.
");
}
else {
bCreated = TRUE;
printf("Created file mapping.
");
}
}
else {
printf("Unable to create file mapping, exiting!
");
exit(-1);
}

// map the memory into this process...
lpSharedString = (LPTSTR) MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (lpSharedString == NULL) {
printf("Unable to map into memory, exiting!
");
exit(-1);
}

// initialize the string if necessary...
if (bCreated)
_tcscpy( lpSharedString, INITIAL_STRING);

while (TRUE) {
printf( "Type a string to share, [Enter] to display current string, or "quit":
");

// input string...
_getts( szLocalString);

if (_tcscmp( szLocalString, __TEXT("quit")) == 0) {
// quit...
break;
}
else if (szLocalString[0] == __TEXT('')) {
// show the string...
printf( "Current string is '%s'.
", lpSharedString);
}
else {
// set the string...
_tcscpy( lpSharedString, szLocalString);
}
}

// unmap the memory...
UnmapViewOfFile(lpSharedString);

// close our handle to the file mapping object...
CloseHandle(hMapping);

// exit...
return 0;
}

Anonymous    Jan 01, 2000
Printed
Page 132

Removed the editorial NOTE at the end of this page, that read:

"Just as this book was going to press..."

This note referred to a comment made in the last paragraph on page 110, just
before the sample code.

Anonymous    Jan 01, 2000
Printed
Page 183
A new line of code has been added, just after the eleventh line of code

down on the page. It reads: if (this == &rhs) return(*this);

Anonymous    Jun 01, 2000
Printed
Page 200
The source code listed in Example 7-4 beginning on page 194 had a bug

in it. Basially, the type of the m_cNotEmpty variable was changed from
CMclEvent to CMclSemaphore. If you use this downloadable version of
CMclLinkedLists.h that has the fix in it, then the paragraph in the book
that explains this variable has been changed. That paragraph was on page
200, and began:

"The CMclLinkedList base class provides internal synchronization
using the critical section object..."

Basically, the change was to replace references to the m_cNotEmpty event with
references to the m_cNotEmpty semaphore, although a related minor change to
the last sentence was needed as well. Here's the full text of the revised
paragraph:

"The MclLinkedList base class provides internal synchronization
using the critical section objet m_cCritSec and the semaphore object
m_cNotEmpty. The critical section serializes access to the internal
data structures of the linked list; without it, nodes could be dropped
during simultaneous puts and gets, and chaos would result. The
semaphore object is used for making get operations block until there
is data in the linked list. When a put operation places data onto
the linked list, the m_cNotEmpty semaphore is released. When a get
operation removes the last entry from the list, the semaphore is
naturally reset by the operating system. The actual list manipulation
operations performed by put and get are coordinated by making them
atomic using the critical section."

Anonymous    Jan 01, 2000
Printed
Page 244-247
Change all occurrences of "alterable" to "alertable."

Anonymous   
Printed
Page 311

In the second paragraph, the next to last sentence used to read:

"The variable m_bRun is used to prevent the worker thread from
exiting when there are always jobs in the queue."

This sentence now reads:

"The variable m_bRun is used to allow the worker thread to exit
even if there are still jobs in the queue."

Note that the comment in the accompanying source code is correct. The loop
will exit if either the m_ceControl event is signalled or m_bRun is set by
the Stop method.

Anonymous    Jan 01, 2000
Printed
Page 341

In Example 10-3, Line 3 used to read:

CFixedThreadPool.h

Now reads:

CFixedThreadPool.cpp

Anonymous    Jan 01, 2000
Printed
Page 440
In the last line, "CAnimatorDlg::InitInstance" has been replaced by

"CAnimatorDlg::OnInitDialog".

Anonymous    Jan 01, 2000
Printed
Page 441

{441} On the first line, "InitInstance" has been replaced by "OnInitDialog".

Anonymous    Jan 01, 2000
Printed
Page 503

The heading of the first code example used to read:

Example 14-2. ExceptionFlow Program Output: Fault Scenario

The word "No" was inserted, and the heading now reads:

Example 14-2. ExceptionFlow Program Output: No-Fault Scenario

Anonymous    Mar 01, 1999
Printed
Page 699

[699] Change the index entry for "alterable waits" to "alertable waits."

Anonymous