| Previous | Main | Next | Site Index | Download | Disclaimer | Privacy |


 

 

 

 

 

WINDOWS THREAD SYNCHRONIZATION REFERENCES 3

 

 

 

 

 

 

The Windows Process, thread and synchronization: Functions, structures and other related items used in program examples of Windows Process, Thread & Synchronization 1, Windows Process, Thread & Synchronization 2, Windows Process, Thread & Synchronization 3, Windows Process, Thread & Synchronization 4, Windows Process, Thread & Synchronization 5 and Windows Process, Thread & Synchronization 6, wherever applicable. To learn about function you can jump to C & C++ function tutorials.

 

The Page Index:

  1. WriteFile()

  2. FindFirstChangeNotification()

  3. FindNextChangeNotification()

  4. FindCloseChangeNotification()

  5. CreateTimerQueueTimer()

  6. WaitOrTimerCallback()

  7. InitializeSListHead()

  8. InterlockedPushEntrySList()

  9. InterlockedPopEntrySList()

  10. InterlockedFlushSList()

  11. SetWaitableTimer()

  12. CreateWaitableTimer()

  13. DeleteTimerQueue()

  14. DeleteTimerQueueEx()

  15. CreateTimerQueue()

  16. ThreadProc()

  17. PeekMessage()

  18. DispatchMessage()

  19. WaitForInputIdle()

  20. MsgWaitForMultipleObjects()

 

 

WriteFile()

 

Item

Description

Function

WriteFile().

Use

Writes data to a file at the position specified by the file pointer. This function is designed for both synchronous and asynchronous operation.  The WriteFileEx() function is designed solely for asynchronous operation.

Prototype

BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,

  LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);

Parameters

See below.

Return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

See below.

 

Table 1.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Parameters

 

hFile - [in] Handle to the file. The file handle must have been created with the GENERIC_WRITE access right.

For asynchronous write operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by the socket or accept function.

Windows Me/98/95:  For asynchronous write operations, hFile can be a communications resource opened with the FILE_FLAG_OVERLAPPED flag by CreateFile(), or a socket handle returned by socket or accept. You cannot perform asynchronous write operations on mailslots, named pipes, or disk files.

lpBuffer - [in] Pointer to the buffer containing the data to be written to the file.

nNumberOfBytesToWrite - [in] Number of bytes to be written to the file.

A value of zero specifies a null write operation. The behavior of a null write operation depends on the underlying file system. To truncate or extend a file, use the SetEndOfFile() function. Named pipe write operations across a network are limited to 65,535 bytes.

lpNumberOfBytesWritten - [out] Pointer to the variable that receives the number of bytes written. WriteFile() sets this value to zero before doing any work or error checking. If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL. If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL. If this is an overlapped write operation, you can get the number of bytes written by calling GetOverlappedResult(). If hFile is associated with an I/O completion port, you can get the number of bytes written by calling GetQueuedCompletionStatus().

If I/O completion ports are used and you are using a callback routine to free the memory allocated to the OVERLAPPED structure pointed to by the lpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the de-allocation. This memory corruption problem will cause an invalid number of bytes to be returned in this parameter. For Windows Me/98/95:  This parameter cannot be NULL.

lpOverlapped - [in] Pointer to an OVERLAPPED structure. This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED.

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the write operation is complete.

If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile() may return before the write operation has been completed. In this case, WriteFile() returns FALSE and the GetLastError() function returns ERROR_IO_PENDING. This allows the calling process to continue processing while the write operation is being completed. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the write operation. The caller must adjust the position of the file pointer upon completion. If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the write operation starts at the current file position and WriteFile() does not return until the operation has been completed. The system updates the file pointer upon completion. WriteFile() resets the event specified by the hEvent member of the OVERLAPPED structure to a non-signaled state when it begins the I/O operation. Therefore, there is no need for the caller to do so. If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile() does not return until the write operation has been completed. The system updates the file pointer upon completion. Windows Me/98/95:  For operations on files, disks, pipes, or mailslots, this parameter must be NULL; a pointer to an OVERLAPPED structure causes the call to fail. However, the function supports overlapped I/O on serial and parallel ports.

 

Some Remarks

 

The WriteFile() function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests. To cancel all pending asynchronous I/O operations, use the CancelIo() function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED. When writing to a file, the last write time is not fully updated until all handles used for writing have been closed. Therefore, to ensure an accurate last write time, close the file handle immediately after writing to the file.

If part of the file is locked by another process and the write operation overlaps the locked portion, WriteFile() fails.  Accessing the output buffer while a write operation is using the buffer may lead to corruption of the data written from that buffer. Applications must not write to, reallocate, or free the output buffer that a write operation is using until the write operation completes.  An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

  1. File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. To determine a volume's sector size, call the GetDiskFreeSpace() function.

  2. File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.

  3. Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). One way to sector align buffers is to use the VirtualAlloc() function to allocate the buffers. This function allocates memory that is aligned on addresses that are integer multiples of the system's page size. Because both page and volume sector sizes are powers of 2, memory aligned by multiples of the system's page size is also aligned by multiples of the volume's sector size.

 

Note that the time stamps may not be updated correctly for a remote file. To ensure consistent results, use unbuffered I/O.  The system interprets zero bytes to write as specifying a null write operation and WriteFile() does not truncate or extend the file. To truncate or extend a file, use the SetEndOfFile() function. When writing to a non-blocking, byte-mode pipe handle with insufficient buffer space, WriteFile() returns TRUE with:

*lpNumberOfBytesWritten < nNumberOfBytesToWrite

When an application uses the WriteFile() function to write to a pipe, the write operation may not finish if the pipe buffer is full. The write operation is completed when a read operation (using the ReadFile() function) makes more buffer space available. If the anonymous read pipe handle has been closed and WriteFile() attempts to write using the corresponding anonymous write pipe handle, the function returns FALSE and GetLastError() returns ERROR_BROKEN_PIPE. Characters can be written to the screen buffer using WriteFile() with a handle to console output. The exact behavior of the function is determined by the console mode. The data is written to the current cursor position. The cursor position is updated after the write operation. If you are attempting to write to a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode() function with SEM_NOOPENFILEERRORBOX.

 

FindFirstChangeNotification()

 

Item

Description

Function

FindFirstChangeNotification().

Use

To create a change notification handle and sets up initial change notification filter conditions. A wait on a notification handle succeeds when a change matching the filter conditions occurs in the specified directory or subtree. However, the function does not indicate the change that satisfied the wait condition.  To retrieve information about the specific change as part of the notification, use the ReadDirectoryChangesW() function.

Prototype

HANDLE FindFirstChangeNotification( LPCTSTR lpPathName, BOOL bWatchSubtree, DWORD dwNotifyFilter);

Parameters

See below.

Return value

If the function succeeds, the return value is a handle to a find change notification object.  If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError().  If the network redirector or the target file system does not support this operation, the function fails with ERROR_INVALID_FUNCTION.

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.  The wait functions can monitor the specified directory or subtree by using the handle returned by the FindFirstChangeNotification() function. A wait is satisfied when one of the filter conditions occurs in the monitored directory or subtree.  After the wait has been satisfied, the application can respond to this condition and continue monitoring the directory by calling the FindNextChangeNotification() function and the appropriate wait function. When the handle is no longer needed, it can be closed by using the FindCloseChangeNotification() function.

Windows Me/98/95:  FindFirstChangeNotificationW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.

 

Table 2.

 

Parameters

 

lpPathName - [in] Pointer to a null-terminated string that specifies the path of the directory to watch.

In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File.  For Windows Me/98/95:  This string must not exceed MAX_PATH characters.

bWatchSubtree - [in] Specifies whether the function will monitor the directory or the directory tree. If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory; if it is FALSE, it monitors only the specified directory.

dwNotifyFilter - [in] Filter conditions that satisfy a change notification wait. This parameter can be one or more of the following values.

 

Value

Meaning

FILE_NOTIFY_CHANGE_FILE_NAME

Any file name change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a file name.

FILE_NOTIFY_CHANGE_DIR_NAME

Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory.

FILE_NOTIFY_CHANGE_ATTRIBUTES

Any attribute change in the watched directory or subtree causes a change notification wait operation to return.

FILE_NOTIFY_CHANGE_SIZE

Any file-size change in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.

FILE_NOTIFY_CHANGE_LAST_WRITE

Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.

FILE_NOTIFY_CHANGE_SECURITY

Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.

 

Table 3

 

FindNextChangeNotification()

 

Item

Description

Function

FindNextChangeNotification().

Use

To request that the operating system signal a change notification handle the next time it detects an appropriate change.

Prototype

BOOL FindNextChangeNotification(HANDLE hChangeHandle);

Parameters

hChangeHandle - [in] Handle to a change notification handle created by the FindFirstChangeNotification() function.

Return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

After the FindNextChangeNotification() function returns successfully, the application can wait for notification that a change has occurred by using the wait functions.  If a change occurs after a call to FindFirstChangeNotification() but before a call to FindNextChangeNotification(), the operating system records the change. When FindNextChangeNotification() is executed, the recorded change immediately satisfies a wait for the change notification.  FindNextChangeNotification() should not be used more than once on the same handle without using one of the wait functions. An application may miss a change notification if it uses FindNextChangeNotification() when there is a change request outstanding.  When hChangeHandle is no longer needed, close it by using the FindCloseChangeNotification() function.

 

Table 4.

 

FindCloseChangeNotification()

 

Item

Description

Function

FindCloseChangeNotification().

Use

To stop change notification handle monitoring.

Prototype

BOOL FindCloseChangeNotification(HANDLE hChangeHandle);

Parameters

hChangeHandle - [in] Handle to a change notification handle created by the FindFirstChangeNotification() function.

Return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

After the FindCloseChangeNotification() function is called, the handle specified by the hChangeHandle parameter cannot be used in subsequent calls to either the FindNextChangeNotification() or FindCloseChangeNotification() function.  Change notifications can also be used in the wait functions.

 

Table 5.

 

CreateTimerQueueTimer()

 

Item

Description

Function

CreateTimerQueueTimer().

Use

Creates a timer-queue timer. This timer expires at the specified due time, then after every specified period. When the timer expires, the callback() function is called.

Prototype

BOOL CreateTimerQueueTimer( PHANDLE phNewTimer, HANDLE TimerQueue, WAITORTIMERCALLBACK Callback, PVOID Parameter, DWORD DueTime, DWORD Period, ULONG Flags);

Parameters

See below.

Return value

If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

See below.

 

Table 6.

 

Parameter

 

phNewTimer - [out] Pointer to a buffer that receives a handle to the timer-queue timer on return. When this handle has expired and is no longer required, release it by calling DeleteTimerQueueTimer().

TimerQueue - [in] Handle to a timer queue. This handle is returned by the CreateTimerQueue() function. If this parameter is NULL, the timer is associated with the default timer queue.

Callback - [in] Pointer to the application-defined function of type WAITORTIMERCALLBACK to be executed when the timer expires.

Parameter - [in] Single parameter value that will be passed to the callback function.

DueTime - [in] Amount of time to elapse before the timer is to be set to the signaled state for the first time, in milliseconds.

Period - [in] Period of the timer, in milliseconds. If this parameter is zero, the timer is signaled once. If this parameter is greater than zero, the timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled.

Flags - [in] This parameter can be one or more of the following values.

 

Value

Meaning

WT_EXECUTEINTIMERTHREAD

The callback() function is invoked by the timer thread itself. This flag should be used only for short tasks or it could affect other timer operations.  The callback function is queued as an APC. It should not perform alertable wait operations.

WT_EXECUTEINIOTHREAD

The callback() function is queued to an I/O worker thread. This flag should be used if the function should be executed in a thread that waits in an alertable state. The callback function is queued as an APC. Be sure to address reentrancy issues if the function performs an alertable wait operation.

WT_EXECUTEINPERSISTENTTHREAD

The callback() function is queued to a thread that never terminates. It does not guarantee that the same thread is used each time. This flag should be used only for short tasks or it could affect other timer operations.  Note that currently no worker thread is truly persistent, although no worker thread will terminate if there are any pending I/O requests.

WT_EXECUTELONGFUNCTION

The callback function can perform a long wait. This flag helps the system to decide if it should create a new thread.

WT_EXECUTEONLYONCE

The timer will be set to the signaled state only once.

WT_TRANSFER_IMPERSONATION

Callback() functions will use the current access token, whether it is a process or impersonation token. If this flag is not specified, callback functions execute only with the process token.  Windows XP and Windows 2000:  This flag is not supported until Windows XP SP2 and Windows Server 2003.

 

Table 7

 

Some Remarks

 

If the DueTime and Period parameters are both nonzero, the timer will be signaled first at the due time, then periodically. The callback() is called every time the period elapses, whether or not the previous callback has finished executing. Callback() functions are queued to the thread pool. These threads are subject to scheduling delays, so the timing can vary depending on what else is happening in the application or the system. To cancel a timer, call the DeleteTimerQueueTimer() function. To cancel all timers in a timer queue, call the DeleteTimerQueueEx() function. By default, the thread pool has a maximum of 500 threads. To raise this limit, use the WT_SET_MAX_THREADPOOL_THREAD macro defined in winnt.h.

#define WT_SET_MAX_THREADPOOL_THREADS(Flags,Limit) ((Flags)|=(Limit)<<16)

Use this macro when specifying the Flags parameter. The macro parameters are the desired flags and the new limit (up to (2<<16)-1 threads). However, note that your application can improve its performance by keeping the number of worker threads low.  To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0500 or later.

 

WaitOrTimerCallback()

 

Item

Description

Function

WaitOrTimerCallback().

Use

Is an application-defined function that serves as the starting address for a timer callback or a registered wait callback. Specify this address when calling the CreateTimerQueueTimer(), RegisterWaitForSingleObject() function.  The WAITORTIMERCALLBACK type defines a pointer to this callback() function. WaitOrTimerCallback() is a placeholder for the application-defined function name.

Prototype

VOID CALLBACK WaitOrTimerCallback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);

Parameters

lpParameter - Receives the thread data passed to the function using a parameter of the CreateTimerQueueTimer() or RegisterWaitForSingleObject() function.

TimerOrWaitFired - If this parameter is TRUE, the wait timed out. If this parameter is FALSE, the wait event has been signaled. This parameter is always TRUE for timer callbacks.

Return value

This function does not return a value.

Include file

<windows.h>

Remark

This callback function must not call the TerminateThread() function.

 

Table 8.

 

InitializeSListHead()

 

Item

Description

Function

InitializeSListHead()

Use

Initializes the head of a singly linked list.

Prototype

void InitializeSListHead(PSLIST_HEADER ListHead);

Parameters

ListHead - Pointer to an SLIST_HEADER structure that represents the head of a singly linked list. This structure is for system use only.

Return value

This function does not return a value.

Include file

<windows.h>

Remark

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.  To add items to the list, use the InterlockedPushEntrySList() function. To remove items from the list, use the InterlockedPopEntrySList() function.

 

Table 9.

 

InterlockedPushEntrySList()

 

Item

Description

Function

InterlockedPushEntrySList().

Use

Inserts an item at the front of a singly linked list. Access to the list is synchronized on a multiprocessor system.

Prototype

PSLIST_ENTRY InterlockedPushEntrySList( PSLIST_HEADER ListHead, PSLIST_ENTRY ListEntry);

Parameters

ListHead - Pointer to an SLIST_HEADER structure that represents the head of a singly linked list. This structure is for system use only.

ListEntry - Pointer to an SLIST_ENTRY structure that represents an item in a singly linked list.

Return value

The return value is the previous first item in the list. If the list was previously empty, the return value is NULL.

Include file

<windows.h>

Remark

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.

 

Table 10.

 

InterlockedPopEntrySList()

 

Item

Description

Function

InterlockedPopEntrySList().

Use

Removes an item from the front of a singly linked list. Access to the list is synchronized on a multiprocessor system.

Prototype

PSLIST_ENTRY InterlockedPopEntrySList( PSLIST_HEADER ListHead);

Parameters

ListHead - Pointer to an SLIST_HEADER structure that represents the head of a singly linked list. This structure is for system use only.

Return value

The return value is a pointer to the item removed from the list. If the list is empty, the return value is NULL.

Include file

<windows.h>

Remark

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.

 

Table 11.

 

InterlockedFlushSList()

 

Item

Description

Function

InterlockedFlushSList().

Use

Removes all items from a singly linked list. Access to the list is synchronized on a multiprocessor system.

Prototype

PSLIST_ENTRY InterlockedFlushSList(PSLIST_HEADER ListHead);

Parameters

ListHead - Pointer to an SLIST_HEADER structure that represents the head of the singly linked list. This structure is for system use only.

Return value

The return value is a pointer to the items removed from the list. If the list is empty, the return value is NULL.

Include file

<windows.h>

Remark

All list items must be aligned on a heap allocation boundary. Unaligned items can cause unpredictable results.

 

Table 12.

 

SetWaitableTimer()

 

Item

Description

Function

SetWaitableTimer().

Use

Activates the specified waitable timer. When the due time arrives, the timer is signaled and the thread that set the timer calls the optional completion routine.

Prototype

BOOL SetWaitableTimer( HANDLE hTimer, const LARGE_INTEGER* pDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, BOOL fResume );

Parameters

See below.

Return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

Timers are initially inactive. To activate a timer, call SetWaitableTimer(). If the timer is already active when you call SetWaitableTimer(), the timer is stopped, then it is reactivated. Stopping the timer in this manner does not set the timer state to signaled, so threads blocked in a wait operation on the timer remain blocked.

When the specified due time arrives, the timer becomes inactive and the APC is queued to the thread that set the timer. The state of the timer is set to signaled, the timer is reactivated using the specified period, and the thread that set the timer calls the completion routine when it enters an alertable wait state. For more information, see QueueUserAPC(). If the thread that set the timer exits before the timer elapses, the timer is cancelled. If you call SetWaitableTimer() on a timer that has been set by another thread and that thread is not in an alertable state, the completion routine is cancelled. When a manual-reset timer is set to the signaled state, it remains in this state until SetWaitableTimer() is called to reset the timer. As a result, a periodic manual-reset timer is set to the signaled state when the initial due time arrives and remains signaled until it is reset. When a synchronization timer is set to the signaled state, it remains in this state until a thread completes a wait operation on the timer object. To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0400 or later.

 

Table 13.

 

Parameters

 

hTimer - [in] Handle to the timer object. The CreateWaitableTimer() or OpenWaitableTimer() function returns this handle.

The handle must have the TIMER_MODIFY_STATE access right.

pDueTime - [in] Time after which the state of the timer is to be set to signaled, in 100 nanosecond intervals. Use the format described by the FILETIME structure. Positive values indicate absolute time. Be sure to use a UTC-based absolute time, as the system uses UTC-based time internally. Negative values indicate relative time. The actual timer accuracy depends on the capability of your hardware.

lPeriod - [in] Period of the timer, in milliseconds. If lPeriod is zero, the timer is signaled once. If lPeriod is greater than zero, the timer is periodic. A periodic timer automatically reactivates each time the period elapses, until the timer is canceled using the CancelWaitableTimer() function or reset using SetWaitableTimer(). If lPeriod is less than zero, the function fails.

pfnCompletionRoutine - [in] Pointer to an optional completion routine. The completion routine is application-defined function of type PTIMERAPCROUTINE to be executed when the timer is signaled.

lpArgToCompletionRoutine - [in] Pointer to a structure that is passed to the completion routine.

fResume - [in] If this parameter is TRUE, restores a system in suspended power conservation mode when the timer state is set to signaled. Otherwise, the system is not restored. If the system does not support a restore, the call succeeds, but GetLastError() returns ERROR_NOT_SUPPORTED.

 

CreateWaitableTimer()

 

Item

Description

Function

CreateWaitableTimer().

Use

Creates or opens a waitable timer object.

Prototype

HANDLE CreateWaitableTimer( LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset,

  LPCTSTR lpTimerName);

Parameters

See below.

Return value

If the function succeeds, the return value is a handle to the timer object. If the named timer object exists before the function call, the function returns a handle to the existing object and GetLastError() returns ERROR_ALREADY_EXISTS.  If the function fails, the return value is NULL. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.  More remarks below.

 

Table 14.

 

Parameters

 

lpTimerAttributes

[in] Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new timer object and determines whether child processes can inherit the returned handle.

If lpTimerAttributes is NULL, the timer object gets a default security descriptor and the handle cannot be inherited. The ACLs in the default security descriptor for a timer come from the primary or impersonation token of the creator.

bManualReset - [in] If this parameter is TRUE, the timer is a manual-reset notification timer. Otherwise, the timer is a synchronization timer.

lpTimerName - [in] Pointer to a null-terminated string specifying the name of the timer object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. If lpTimerName is NULL, the timer object is created without a name. If lpTimerName matches the name of an existing event, semaphore, mutex, job, or file-mapping object, the function fails and GetLastError() returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space. Terminal Services:  The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). Windows XP Home Edition:  Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users. Windows 2000:  If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character. Windows NT:  The name can contain any character except the backslash character. Windows 98/Me:  The name can contain any character except the backslash character. The empty string ("") is a valid object name.

 

Some Remarks

 

The handle returned by CreateWaitableTimer() is created with the TIMER_ALL_ACCESS access right. This handle can be used in any function that requires a handle to a timer object.  Any thread of the calling process can specify the timer object handle in a call to one of the wait functions. Multiple processes can have handles to the same timer object, enabling use of the object for interprocess synchronization.

  1. A process created by the CreateProcess() function can inherit a handle to a timer object if the lpTimerAttributes parameter of CreateWaitableTimer() enables inheritance.

  2. A process can specify the timer object handle in a call to the DuplicateHandle() function. The resulting handle can be used by another process.

  3. A process can specify the name of a timer object in a call to the OpenWaitableTimer() or CreateWaitableTimer() function.

 

Use the CloseHandle() function to close the handle. The system closes the handle automatically when the process terminates. The timer object is destroyed when its last handle has been closed.

For Windows Me/98:  CreateWaitableTimerW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems. To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0400 or later.

 

DeleteTimerQueue()

 

Item

Description

Function

DeleteTimerQueue().

Use

Deletes a timer queue. Any pending timers in the queue are canceled and deleted.  Note that this function is obsolete and has been replaced by the DeleteTimerQueueEx() function.

Prototype

BOOL DeleteTimerQueue(HANDLE TimerQueue);

Parameters

TimerQueue - [in] Handle to a timer queue. This handle is returned by the CreateTimerQueue() function.

Return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

 <windows.h>

Remark

DeleteTimerQueue() does not wait for all callback functions associated with the timer to complete.  To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0500 or later.

 

Table 15.

 

DeleteTimerQueueEx()

 

Item

Description

Function

DeleteTimerQueueEx().

Use

Deletes a timer queue. Any pending timers in the queue are canceled and deleted.

Prototype

BOOL DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent);

Parameters

TimerQueue - [in] Handle to a timer queue. This handle is returned by the CreateTimerQueue() function.

CompletionEvent - [in] Handle to the event object to be signaled when the function is successful and all callback functions have completed. This parameter can be NULL.

If this parameter is INVALID_HANDLE_VALUE, the function waits for all callback functions to complete before returning. If this parameter is NULL, the function marks the timer for deletion and returns immediately. However, most callers should wait for the callback function to complete so they can perform any needed cleanup.

Return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

Do not make blocking calls to DeleteTimerQueueEx() from within a timer callback.  To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0500 or later.

 

Table 16.

 

CreateTimerQueue()

 

Item

Description

Function

CreateTimerQueue().

Use

Creates a queue for timers. Timer-queue timers are lightweight objects that enable you to specify a callback function to be called at a specified time.

Prototype

HANDLE CreateTimerQueue(void);

Parameters

This function has no parameters.

Return value

If the function succeeds, the return value is a handle to the timer queue. This handle can be used only in functions that require a handle to a timer queue.  If the function fails, the return value is NULL. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

To add a timer to the queue, call the CreateTimerQueueTimer() function. To remove a timer from the queue, call the DeleteTimerQueueTimer() function.  When you are finished with the queue of timers, call the DeleteTimerQueueEx() function to delete the timer queue. Any pending timers in the queue are canceled and deleted.  To compile an application that uses this function, define the _WIN32_WINNT macro as 0x0500 or later.

 

Table 17.

 

ThreadProc()

 

Item

Description

Function

ThreadProc().

Use

Is an application-defined function that serves as the starting address for a thread. Specify this address when calling the CreateThread() or CreateRemoteThread() function. The LPTHREAD_START_ROUTINE type defines a pointer to this callback function. ThreadProc() is a placeholder for the application-defined function name.

Prototype

DWORD WINAPI ThreadProc(LPVOID lpParameter);

Parameters

lpParameter - [in] Thread data passed to the function using the lpParameter parameter of the CreateThread() or CreateRemoteThread() function.

Return value

The function should return a value that indicates its success or failure.

Include file

<windows.h>

Remark

A process can obtain the return value of the ThreadProc() of a thread it created with CreateThread() by calling the GetExitCodeThread() function. A process cannot obtain the return value from the ThreadProc() of a thread it created with CreateRemoteThread().

 

Table 18.

 

PeekMessage()

 

Item

Description

Function

PeekMessage().

Use

Dispatches incoming sent messages, checks the thread message queue for a posted message, and retrieves the message (if any exist).

Prototype

BOOL PeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT RemoveMsg );

Parameters

See below.

Return value

If a message is available, the return value is nonzero. If no messages are available, the return value is zero.

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions on Windows NT, Windows 2000, and Windows XP. More remarks below.

 

Table 19.

 

 

Parameters

 

lpMsg - [out] Pointer to an MSG structure that receives message information.

hWnd - [in] Handle to the window whose messages are to be examined. The window must belong to the current thread. If hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread. If hWnd is INVALID_HANDLE_VALUE, PeekMessage() retrieves messages whose hWnd value is NULL, as posted by the PostThreadMessage() function.

wMsgFilterMin - [in] Specifies the value of the first message in the range of messages to be examined. Use WM_KEYFIRST to specify the first keyboard message or WM_MOUSEFIRST to specify the first mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage() returns all available messages (that is, no range filtering is performed).

wMsgFilterMax - [in] Specifies the value of the last message in the range of messages to be examined. Use WM_KEYLAST to specify the last keyboard message or WM_MOUSELAST to specify the last mouse message. If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage() returns all available messages (that is, no range filtering is performed).

wRemoveMsg - [in] Specifies how messages are handled. This parameter can be one of the following values. PM_NOREMOVE - Messages are not removed from the queue after processing by PeekMessage(). PM_REMOVE - Messages are removed from the queue after processing by PeekMessage(). You can optionally combine the value PM_NOYIELD with either PM_NOREMOVE or PM_REMOVE. This flag prevents the system from releasing any thread that is waiting for the caller to go idle (see WaitForInputIdle()). By default, all message types are processed. To specify that only certain message should be processed, specify one or more of the following values:

  1. PM_QS_INPUT - Windows 98/Me, Windows 2000/XP: Process mouse and keyboard messages.

  2. PM_QS_PAINT - Windows 98/Me, Windows 2000/XP: Process paint messages.

  3. PM_QS_POSTMESSAGE - Windows 98/Me, Windows 2000/XP: Process all posted messages, including timers and hotkeys.

  4. PM_QS_SENDMESSAGE - Windows 98/Me, Windows 2000/XP: Process all sent messages.

 

Remarks

 

PeekMessage() retrieves messages associated with the window identified by the hWnd parameter or any of its children as specified by the IsChild() function, and within the range of message values given by the wMsgFilterMin and wMsgFilterMax parameters. Note that an application can only use the low word in the wMsgFilterMin and wMsgFilterMax parameters; the high word is reserved for the system. Note that PeekMessage() always retrieves WM_QUIT messages, no matter which values you specify for wMsgFilterMin and wMsgFilterMax. During this call, the system delivers pending messages that were sent to windows owned by the calling thread using the SendMessage(), SendMessageCallback(), SendMessageTimeout(), or SendNotifyMessage() function. The system may also process internal events. Messages are processed in the following order:

 

  1. Sent messages.

  2. Posted messages.

  3. Input (hardware) messages and system internal events.

  4. Sent messages (again).

  5. WM_PAINT messages.

  6. WM_TIMER messages.

 

To retrieve input messages before posted messages, use the wMsgFilterMin and wMsgFilterMax parameters. The PeekMessage() function normally does not remove WM_PAINT messages from the queue. WM_PAINT messages remain in the queue until they are processed. However, if a WM_PAINT message has a NULL update region, PeekMessage() does remove it from the queue. Windows XP: If a top-level window stops responding to messages for more than several seconds, the system considers the window to be hung and replaces it with a ghost window that has the same z-order, location, size, and visual attributes. This allows the user to move it, resize it, or even close the application. However, these are the only actions available because the application is actually hung. When an application is being debugged, the system does not generate a ghost window. Windows 95/98/Me: PeekMessageW() is supported by the Microsoft® Layer for Unicode (MSLU). To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.

 

WaitForInputIdle()

 

Item

Description

Function

WaitForInputIdle().

Use

Waits until the specified process is waiting for user input with no input pending, or until the time-out interval has elapsed.

Prototype

DWORD WaitForInputIdle( HANDLE hProcess, DWORD dwMilliseconds);

Parameters

hProcess - [in] Handle to the process. If this process is a console application or does not have a message queue, WaitForInputIdle returns immediately.

dwMilliseconds - [in] Time-out interval, in milliseconds. If dwMilliseconds is INFINITE, the function does not return until the process is idle.

Return value

The following table shows the possible return values for this function.

  1. 0 - The wait was satisfied successfully.

  2. WAIT_TIMEOUT - The wait was terminated because the time-out interval elapsed.

  3. WAIT_FAILED - An error occurred. To get extended error information, use the GetLastError() function.

Include file

<windows.h>

Remark

The WaitForInputIdle() function enables a thread to suspend its execution until the specified process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronizing a parent process and a newly created child process. When a parent process creates a child process, the CreateProcess() function returns without waiting for the child process to finish its initialization. Before trying to communicate with the child process, the parent process can use WaitForInputIdle() to determine when the child's initialization has been completed. For example, the parent process should use WaitForInputIdle() before trying to find a window associated with the child process. The WaitForInputIdle() function can be used at any time, not just during application startup.

 

Table 20.

 

DispatchMessage()

 

Item

Description

Function

DispatchMessage().

Use

Dispatches a message to a window procedure. It is typically used to dispatch a message retrieved by the GetMessage() function.

Prototype

LRESULT DispatchMessage(const MSG *lpmsg);

Parameters

lpmsg - [in] Pointer to an MSG structure that contains the message.

Return value

The return value specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored.

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions on Windows NT, Windows 2000, and Windows XP.  The MSG structure must contain valid message values. If the lpmsg parameter points to a WM_TIMER message and the lParam parameter of the WM_TIMER message is not NULL, lParam points to a function that is called instead of the window procedure.

Note that the application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. However, to permit the user to move to and to select controls by using the keyboard, the application must call IsDialogMessage(). For Windows 95/98/Me: DispatchMessageW() is supported by the Microsoft® Layer for Unicode (MSLU). To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.

 

Table 21.

 

MsgWaitForMultipleObjects()

 

Item

Description

Function

MsgWaitForMultipleObjects().

Use

Returns when any one or all of the specified objects are in the signaled state or the time-out interval elapses. The objects can include input event objects, which you specify using the dwWakeMask parameter. To enter an alertable wait state, use the MsgWaitForMultipleObjectsEx() function.

Prototype

DWORD MsgWaitForMultipleObjects( DWORD nCount, const HANDLE* pHandles, BOOL bWaitAll, DWORD dwMilliseconds, DWORD dwWakeMask );

Parameters

See below.

Return value

See below.

Include file

<windows.h>

Remark

See below.

 

Table 22.

 

Parameters

 

nCount - [in] Number of object handles in the array pointed to by pHandles. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS minus one.

pHandles - [in] Pointer to an array of object handles. For a list of the object types whose handles can be specified, see the Remarks section. The array can contain handles of objects of different types. It may not contain multiple copies of the same handle. If one of these handles is closed while the wait is still pending, the function's behavior is undefined. The handles must have the SYNCHRONIZE access right. For Windows Me/98/95:  No handle may be a duplicate of another handle created using DuplicateHandle().

bWaitAll - [in] If this parameter is TRUE, the function returns when the states of all objects in the pHandles array have been set to signaled and an input event has been received. If this parameter is FALSE, the function returns when the state of any one of the objects is set to signaled or an input event has been received. In this case, the return value indicates the object whose state caused the function to return.

dwMilliseconds - [in] Time-out interval, in milliseconds. The function returns if the interval elapses, even if the criteria specified by the bWaitAll or dwWakeMask parameter have not been met. If dwMilliseconds is zero, the function tests the states of the specified objects and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.

dwWakeMask - [in] Input types for which an input event object handle will be added to the array of object handles. This parameter can be any combination of the following values.

 

Value

Meaning

QS_ALLEVENTS

An input, WM_TIMER, WM_PAINT, WM_HOTKEY, or posted message is in the queue. This value is a combination of QS_INPUT, QS_POSTMESSAGE, QS_TIMER, QS_PAINT, and QS_HOTKEY.

QS_ALLINPUT

Any message is in the queue. This value is a combination of QS_INPUT, QS_POSTMESSAGE, QS_TIMER, QS_PAINT, QS_HOTKEY, and QS_SENDMESSAGE.

QS_ALLPOSTMESSAGE

A posted message is in the queue. This value is cleared when you call GetMessage() or PeekMessage() without filtering messages.

QS_HOTKEY

A WM_HOTKEY message is in the queue.

QS_INPUT

An input message is in the queue. This value is a combination of QS_MOUSE and QS_KEY. For Windows 2003 Server and Windows XP:  This value also includes QS_RAWINPUT.

QS_KEY

A WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, or WM_SYSKEYDOWN message is in the queue.

QS_MOUSE

A WM_MOUSEMOVE message or mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on). This value is a combination of QS_MOUSEMOVE and QS_MOUSEBUTTON.

QS_MOUSEBUTTON

A mouse-button message (WM_LBUTTONUP, WM_RBUTTONDOWN, and so on).

QS_MOUSEMOVE

A WM_MOUSEMOVE message is in the queue.

QS_PAINT

A WM_PAINT message is in the queue.

QS_POSTMESSAGE

A posted message is in the queue. This value is cleared when you call GetMessage() or PeekMessage(), whether or not you are filtering messages.

QS_RAWINPUT

A raw input message is in the queue. For Windows 2000/NT and Windows Me/98/95:  This value is not supported.

QS_SENDMESSAGE

A message sent by another thread or application is in the queue.

QS_TIMER

A WM_TIMER message is in the queue.

 

Table 23

 

Return Values

 

If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values.

 

Return code

Description

WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1)

If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled. If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the pHandles array index of the object that satisfied the wait.

WAIT_OBJECT_0 + nCount

New input of the type specified in the dwWakeMask parameter is available in the thread's input queue. Functions such as PeekMessage(), GetMessage(), and WaitMessage() mark messages in the queue as old messages. Therefore, after you call one of these functions, a subsequent call to MsgWaitForMultipleObjects() will not return until new input of the specified type arrives.

This value is also returned upon the occurrence of a system event that requires the thread's action, such as foreground activation. Therefore, MsgWaitForMultipleObjects() can return even though no appropriate input is available and even if dwWakeMask is set to 0. If this occurs, call GetMessage() or PeekMessage() to process the system event before trying the call to MsgWaitForMultipleObjects() again.

WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount – 1)

If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object. If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the pHandles array index of an abandoned mutex object that satisfied the wait.

WAIT_TIMEOUT

The time-out interval elapsed and the conditions specified by the bWaitAll and dwWakeMask parameters were not satisfied.

 

Table 24

 

If the function fails, the return value is WAIT_FAILED. To get extended error information, call GetLastError().

 

Some Remarks

 

The MsgWaitForMultipleObjects() function determines whether the wait criteria have been met. If the criteria have not been met, the calling thread enters the wait state. It uses no processor time while waiting for the conditions of the wait criteria to be met. When bWaitAll is TRUE, the function does not modify the states of the specified objects until the states of all objects have been set to signaled. For example, a mutex can be signaled, but the thread does not get ownership until the states of the other objects have also been set to signaled. In the meantime, some other thread may get ownership of the mutex, thereby setting its state to non-signaled.

When bWaitAll is TRUE, the function's wait is completed only when the states of all objects have been set to signaled and an input event has been received. Therefore, setting bWaitAll to TRUE prevents input from being processed until the state of all objects in the pHandles array have been set to signaled. For this reason, if you set bWaitAll to TRUE, you should use a short timeout value in dwMilliseconds. If you have a thread that creates windows waiting for all objects in the pHandles array, including input events specified by dwWakeMask, with no timeout interval, the system will deadlock. This is because threads that create windows must process messages. DDE sends message to all windows in the system. Therefore, if a thread creates windows, do not set the bWaitAll parameter to TRUE in calls to MsgWaitForMultipleObjects() made from that thread. Note  MsgWaitForMultipleObjects() does not return if there is unread input of the specified type in the message queue after the thread has called a function to check the queue. This is because functions such as PeekMessage(), GetMessage(), GetQueueStatus(), and WaitMessage() check the queue and then change the state information for the queue so that the input is no longer considered new. A subsequent call to MsgWaitForMultipleObjects() will not return until new input of the specified type arrives. The existing unread input (received prior to the last time the thread checked the queue) is ignored. The function modifies the state of some types of synchronization objects. Modification occurs only for the object or objects whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one. When bWaitAll is FALSE, and multiple objects are in the signaled state, the function chooses one of the objects to satisfy the wait; the states of the objects not selected are unaffected. The MsgWaitForMultipleObjects() function can specify handles of any of the following object types in the pHandles array:

  1. Change notification.

  2. Console input.

  3. Event.

  4. Job.

  5. Memory resource notification.

  6. Mutex.

  7. Process.

  8. Semaphore.

  9. Thread.

  10. Waitable timer.

 

The QS_ALLPOSTMESSAGE and QS_POSTMESSAGE flags differ in when they are cleared. QS_POSTMESSAGE is cleared when you call GetMessage() or PeekMessage(), whether or not you are filtering messages. QS_ALLPOSTMESSAGE is cleared when you call GetMessage() or PeekMessage() without filtering messages (wMsgFilterMin and wMsgFilterMax are 0). This can be useful when you call PeekMessage() multiple times to get messages in different ranges.

 

 

------------------------------------------------Part 5/5---------------------------------------------------

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Microsoft Visual C++, online MSDN.

  2. Structure, enum, union and typedef story can be found at C enum, typedef, struct etc..

  3. For Multibytes, Unicode characters and Localization please refer to Unicode & Multibyte 1 (Story) and Unicode & Multibyte 2 (Implementation).

  4. Check the best selling C / C++ and Windows books at Amazon.com.

 

 

 

 

 

 

| Previous | Main | Next | Site Index | Download | Disclaimer | Privacy |