jeśli chodzi o SendMessage, jest synchronizacja między wątkami {i to dosyć nietypowa} (właśnie dlatego trzeba wołać SendMessage, żeby wykonać jakiś komunikat okna, a nie CallWindowProc, czy bezpośrednio calnąć procke okna co by było o niebo szybsze)
kiedyś myślałem, że SendMessage po prostu szuka procedurki okna po podanym hwnd i ją bezpośrednio woła (czyli opcja bez synchronizacji), od czasu kiedy wykonałem zakleszczenie funkcją GetWindowText wiem, że działanie jest ciut bardziej złożone...
zakleszczenie polegało na tym, że miałem wątek główny pompujący komunikaty i z nim związane okno, wątek poboczny coś tam robił... w pewnym momencie zawieszałem wątek główny a pracował wątek poboczny i teraz jeśli w takim wątku pobocznym wywołać SendMessage dla okna związanego z wątkiem głównym jest zakleszczenie...
dlaczego? bo SendMessage zatrzymuje działanie wątku(o ile jest w innym) i każe przetworzyć komunikat w wątku związanym z oknem, czyli de facto wszystkie komunikaty związane z oknem zostaną zawsze przetworzone w wątku tego okna, nawet gdy SendMessage (czy tam GetWindowText,itp. bo to i tak wszystko wrappery na SendMessage z odpowiednim komunikatem) zostanie wywołane w innym wątku niezwiązanym z oknem, więc jakiś mechanizm synchronizacji jest...
nie wiem dokładnie jak odbywa się przetwarzanie takich komunikatów z osobnych wątków, czy taki komunikat przechodzi pełny obieg w pętli, czyli GetMessage+DispatchMessage (tzn że w pętli wątku okna będzie widać przetwarzanie tego komunikatu wołanego z innego wątku), czy też GetMessage wewnętrznie potajemnie przetworzy taki komunikat, nigdy tego nie sprawdzałem (prawdopodobnie jest opcja 1)
w tym miejscu można zwrócić uwagę na fakt, że SendMessage tak naprawdę na sporo do roboty, bo najpierw musi określić czy wołane jest w wątku okna, czy zewnętrznego, jeśli okna, to pewnie bezpośrednio woła procedurkę okna, natomiast jeśli z innego musi poczekać na cykl pętli w wątku okna, więc na pierwszy rzut oka widać, że wywoływanie SendMessage z zewnętrznego wątku będzie miało dodatkowy narzut czasowy związanego z tą synchronizacją, tym większy im bardziej obciążony jest wątek pompujący komunikaty (dłuższe oczekiwanie na cykl pętli)
teraz odpowiedź na pytanie czy win32 jest thread-safe... właściwie to po części, bo żadnego thread-safe powszechnie rozumianego nie ma (normalnej synchronizacji), ale z założenia zrobione jest to tak, że procedurka okna (przetwarzanie komunikatów) zawsze będzie wykonywana tylko w wątku okna (pompującego komunikaty), nawet gdy SendMessage (i jego wrappery, czyli reszta funkcji GUI) zostanie wywołany w innym wątku, dba o to, aby komunikat przetworzyć w wątku okna, ważne tylko, aby nie zablokować wątku okna, bo wtedy SendMessage z innego wątku da jedynie deadlocka, dzięki którego przypadkowo poznałem ten mechanizm...