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