/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Thread management. * * By Stefan Schimanski. * * Synchronization functions added by Eric Botcazou. * * See readme.txt for copyright information. */ #include "allegro.h" #include "allegro/internal/aintern.h" #include "allegro/platform/aintwin.h" #ifndef SCAN_DEPEND #include #endif #ifndef ALLEGRO_WINDOWS #error something is wrong with the makefile #endif /* COINIT_MULTITHREADED is not defined in objbase.h for MSVC */ #define _COINIT_MULTITHREADED 0 typedef HRESULT(CALLBACK * _CoInitializeEx_ptr) (LPVOID, DWORD); static _CoInitializeEx_ptr _CoInitializeEx = NULL; static int first_call = 1; /* _win_thread_init: * Initializes COM interface for the calling thread. * Attempts to use Distributed COM if available (installed by default * on every 32-bit Windows starting with Win98 and Win NT4). */ void _win_thread_init(void) { HMODULE ole32 = NULL; HWND allegro_wnd = win_get_window(); if (first_call) { first_call = 0; ole32 = GetModuleHandle("OLE32.DLL"); if (ole32 != NULL) { _CoInitializeEx = (_CoInitializeEx_ptr) GetProcAddress( ole32, "CoInitializeEx"); } else { MessageBox(allegro_wnd, "OLE32.DLL can't be loaded.", "Warning", MB_ICONWARNING + MB_OK); } if (_CoInitializeEx == NULL) { MessageBox(allegro_wnd, "Microsoft Distributed COM is not installed on this system. If you have problems " "with this application, please install the DCOM update. You can find it on the " "Microsoft homepage.", "DCOM not found", MB_ICONWARNING + MB_OK); } } if (_CoInitializeEx != NULL) _CoInitializeEx(NULL, _COINIT_MULTITHREADED); else CoInitialize(NULL); } /* _win_thread_exit: * Shuts down COM interface for the calling thread. */ void _win_thread_exit(void) { CoUninitialize(); } /* sys_directx_create_mutex: * Creates a mutex and returns a pointer to it. * Uses Critical Sections because Allegro mutexes are * inner-process synchronization objects only. */ void *sys_directx_create_mutex(void) { CRITICAL_SECTION *cs; cs = malloc(sizeof(CRITICAL_SECTION)); if (!cs) { *allegro_errno = ENOMEM; return NULL; } InitializeCriticalSection(cs); return (void *)cs; } /* sys_directx_destroy_mutex: * Destroys a mutex. */ void sys_directx_destroy_mutex(void *handle) { CRITICAL_SECTION *cs = (CRITICAL_SECTION *)handle; DeleteCriticalSection(cs); free(cs); } /* sys_directx_lock_mutex: * Locks a mutex. */ void sys_directx_lock_mutex(void *handle) { CRITICAL_SECTION *cs = (CRITICAL_SECTION *)handle; EnterCriticalSection(cs); } /* sys_directx_unlock_mutex: * Unlocks a mutex. */ void sys_directx_unlock_mutex(void *handle) { CRITICAL_SECTION *cs = (CRITICAL_SECTION *)handle; LeaveCriticalSection(cs); }