# Call Synchronization

OLE applications must be able to deal correctly with user input while processing one or more calls from OLE or the operating system. OLE provides call synchronization for single-threaded apartments only. Multi-threaded apartments (containing free-threaded threads) do not receive calls while making calls (on the same thread). Multi-threaded apartments cannot make input synchronized calls. Asynchronous calls are converted to synchronous calls in multi-threaded apartments. The message filter is not called for any thread in a multi-threaded apartment. For more information on threading issues, see Processes and Threads.

OLE calls between processes fall into three categories:

- Synchronous calls

- Asynchronous notifications

- Input-synchronized calls

Most of the communication that takes place within OLE is synchronous. When making synchronous calls, the caller waits for the reply before continuing and can receive incoming messages while waiting. OLE enters a modal loop to wait for the reply, receiving and dispatching other messages in a controlled manner.

When sending asynchronous notifications, the caller does not wait for the reply. OLE uses PostMessage or high-level events to send asynchronous notifications, depending on the platform. OLE defines five asynchronous methods:

- IAdviseSink::OnDataChange

- IAdviseSink::OnViewChange

- IAdviseSink::OnRename

- IAdviseSink::OnSave

- IAdviseSink::OnClose

While OLE is processing an asynchronous call, synchronous calls cannot be made. For example, a container application’s implementation of IAdviseSink::OnDataChange cannot contain a call to IPersistStorage::Save.

When making input-synchronized calls, the object called must complete the call before yielding control. This ensures that focus management works correctly and that data entered by the user is processed appropriately. These calls are made by OLE through the Windows SendMessage function, without entering a modal loop. While processing an input-synchronized call, the object called must not call any function or method (including synchronous methods) that might yield control.

The following methods are input synchronized:

- IOleWindow::GetWindow

- IOleInPlaceActiveObject::OnFrameWindowActivate

- IOleInPlaceActiveObject::OnDocWindowActivate

- IOleInPlaceActiveObject::ResizeBorder

- IOleInPlaceUIWindow::GetBorder

- IOleInPlaceUIWindow::RequestBorderSpace

- IOleInPlaceUIWindow::SetBorderSpace

- IOleInPlaceFrame::SetMenu

- IOleInPlaceFrame::SetStatusText

- IOleInPlaceObject::SetObjectRects

To minimize problems that can arise from asynchronous message processing, the majority of OLE method calls are synchronous. With synchronous communication, there is no need for special code to dispatch and handle incoming messages. When an application makes a synchronous method call, OLE enters a modal wait loop that handles the required replies and dispatches incoming messages to applications capable of processing them.

OLE manages method calls by assigning an identifier called a logical thread ID. A new one is assigned when a user selects a menu command or when the application initiates a new OLE operation. Subsequent calls that relate to the initial OLE call are assigned the same logical thread ID as the initial call.