Does win32 PostMessage and GetMessage use release acquire fencing?

Jim Bean 0 Reputation points
2025-02-12T04:04:12.5433333+00:00

I've been looking ALL over for this information explicitly, but I can not find anything documented.

Does PostMessage and GetMessage internally implement or behave like they implement atomic release acquire fencing? Specifically, does PostMessage release fence all memory operations before it, and does GetMessage acquire fence? This would result in global variables finishing their writes in the other thread that contains GetMessage by the time GetMessage is called.

It would seem odd that you would be able to pass pointers via LPARAM if this were not the case. How would it guarantee that some new allocated memory was finished being written in the thread containing GetMessage?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,737 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Jeanine Zhang-MSFT 10,546 Reputation points Microsoft Vendor
    2025-02-12T06:27:17.95+00:00

    Hi

    Welcome to Microsoft Q&A!

    PostMessage:Places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.

    GetMessage:Retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval.

    PostMessage and GetMessage are used to pass the message between threads. In my opinion, PostMessage and GetMessage do not use release-acquire fencing.

    If you want to make sure synchronize memory between multiple threads, you could use the <atomic> functions.

    Thank you

    Jeanine


  2. Darran Rowe 1,426 Reputation points
    2025-02-12T06:31:26.88+00:00

    Have you read the documentation for PostMessage?

    "If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters cannot include pointers. Otherwise, the operation will fail. The functions will return before the receiving thread has had a chance to process the message and the sender will free the memory before it is used."

    WM_USER is 0x0400, so the range below WM_USER is all of the standard well known messages. So there is no thread safety if you post the message to a different thread.


  3. Jim Bean 0 Reputation points
    2025-02-13T22:03:25.41+00:00

    After much discussion with @Darran Rowe , there is a lack of real evidence that PostMessage provides implicit fencing to ensure that writes that occur before PostMessage are visible after GetMessage is called in the receiving thread. Thus, one should not assume any memory operation that is supposed to happen before PostMessage has completed in other threads that are receiving the message, such as a call to the new operator and passing the resulting pointer for user defined messages.

    Win32 API users that assume memory operations are completed across threads before PostMessage are relying on undefined behavior, and the apparently successful functionality could easily be due to the architecture. Thus, one should probably not imitate these API users, and instead use their own synchronization mechanism, as as std::memory_order_release on fences and atomics before PostMessage in the sending thread, and std::memory_order_acquire on fences and atomics after GetMessage in the receiving thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.