Navigation:  Programming Cookbook > External Interfacing >

Overlapped Calls

Previous pageReturn to chapter overviewNext page

Overlapped calls are external calls that the VM performs on a thread other than the main Smalltalk execution thread. These are sometimes called threaded calls, or non-blocking calls.

Overlapped calls are useful where a call is made to a external function that might take some considerable time to complete. Consider for example the URLMon DLL function URLDownloadToFile() that can be used to download arbitrary resources from the internet. It is, however, a blocking call and obviously downloading from the internet can take from seconds to hours. If we were to invoke this function as an ordinary external call, then the entire image would be blocked for the duration of that call. Obviously this is undesirable, so the call is actually defined as follows:

overlappedURLDownloadToFile: pCaller szURL: szURL szFilename: szFilename dwReserved: dwReserved pBSC: pBsc

  "Downloads bits from the Internet and saves them to a file.

      HRESULT URLDownloadToFile(

          LPUNKNOWN pCaller,

          LPCTSTR szURL,

          LPCTSTR szFileName,

          DWORD dwReserved,

          LPBINDSTATUSCALLBACK lpfnCB

  );"

  <overlap stdcall: hresult URLDownloadToFileA IUnknown* lpstr lpstr dword lpvoid>

  ^self invalidCall

 

Note how the external call primitive definition starts with the overlap keyword. This is all that is required to instruct the VM to perform the external call on a separate thread, blocking only the calling Smalltalk Process rather than the entire image. This allows the download from the Internet to complete in the background while the image continues with other work, although if the call is invoked from the foreground, main or UI, process then the image will appear to be blocked but background processes will continue to run.

Another example in the base image is KernelLibrary>>sleep:, which wraps the Win32 Sleep() API:

sleep: anInteger

  "Put the calling Win32 thread to sleep for anInteger milliseconds.

      void Sleep(

          DWORD dwMilliseconds    // sleep duration in millisecs

      );

  N.B. This is an overlapped call, and will not interrupt the execution

  of Dolphin's background threads since it is performed on a separate

  thread. Only the calling Process will be delayed.!

  "

  <overlap stdcall: void Sleep dword>

  ^self invalidCall

 

This can be used as an alternative form of Delay.