/src/rt/monitor_.d
http://github.com/AlexeyProkhin/druntime · D · 255 lines · 195 code · 31 blank · 29 comment · 24 complexity · c3164e30f2af3b51cd4e25238f7f6968 MD5 · raw file
- /**
- * Contains the implementation for object monitors.
- *
- * Copyright: Copyright Digital Mars 2000 - 2011.
- * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
- * Authors: Walter Bright, Sean Kelly
- */
- /* Copyright Digital Mars 2000 - 2011.
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- */
- module rt.monitor_;
- //debug=PRINTF;
- private
- {
- debug(PRINTF) import core.stdc.stdio;
- import core.stdc.stdlib;
- version( linux )
- {
- version = USE_PTHREADS;
- }
- else version( FreeBSD )
- {
- version = USE_PTHREADS;
- }
- else version( OSX )
- {
- version = USE_PTHREADS;
- }
- else version( Solaris )
- {
- version = USE_PTHREADS;
- }
- // This is what the monitor reference in Object points to
- alias Object.Monitor IMonitor;
- alias void delegate(Object) DEvent;
- version( Windows )
- {
- version (DigitalMars) version (Win32)
- pragma(lib, "snn.lib");
- import core.sys.windows.windows;
- struct Monitor
- {
- IMonitor impl; // for user-level monitors
- DEvent[] devt; // for internal monitors
- size_t refs; // reference count
- CRITICAL_SECTION mon;
- }
- }
- else version( USE_PTHREADS )
- {
- import core.sys.posix.pthread;
- struct Monitor
- {
- IMonitor impl; // for user-level monitors
- DEvent[] devt; // for internal monitors
- size_t refs; // reference count
- pthread_mutex_t mon;
- }
- }
- else
- {
- static assert(0, "Unsupported platform");
- }
- Monitor* getMonitor(Object h)
- {
- return cast(Monitor*) h.__monitor;
- }
- void setMonitor(Object h, Monitor* m)
- {
- h.__monitor = m;
- }
- static __gshared int inited;
- }
- /* =============================== Win32 ============================ */
- version( Windows ) version( LDC )
- {
- static __gshared CRITICAL_SECTION _monitor_critsec;
- extern (C) void _STI_monitor_staticctor()
- {
- debug(PRINTF) printf("+_STI_monitor_staticctor()\n");
- if (!inited)
- {
- InitializeCriticalSection(&_monitor_critsec);
- inited = 1;
- }
- debug(PRINTF) printf("-_STI_monitor_staticctor()\n");
- }
- extern (C) void _STD_monitor_staticdtor()
- {
- debug(PRINTF) printf("+_STI_monitor_staticdtor() - d\n");
- if (inited)
- {
- inited = 0;
- DeleteCriticalSection(&_monitor_critsec);
- }
- debug(PRINTF) printf("-_STI_monitor_staticdtor() - d\n");
- }
- extern (C) void _d_monitor_create(Object h)
- {
- /*
- * NOTE: Assume this is only called when h.__monitor is null prior to the
- * call. However, please note that another thread may call this function
- * at the same time, so we can not assert this here. Instead, try and
- * create a lock, and if one already exists then forget about it.
- */
- debug(PRINTF) printf("+_d_monitor_create(%p)\n", h);
- assert(h);
- Monitor *cs;
- EnterCriticalSection(&_monitor_critsec);
- if (!h.__monitor)
- {
- cs = cast(Monitor *)calloc(Monitor.sizeof, 1);
- assert(cs);
- InitializeCriticalSection(&cs.mon);
- setMonitor(h, cs);
- cs.refs = 1;
- cs = null;
- }
- LeaveCriticalSection(&_monitor_critsec);
- if (cs)
- free(cs);
- debug(PRINTF) printf("-_d_monitor_create(%p)\n", h);
- }
- extern (C) void _d_monitor_destroy(Object h)
- {
- debug(PRINTF) printf("+_d_monitor_destroy(%p)\n", h);
- assert(h && h.__monitor && !getMonitor(h).impl);
- DeleteCriticalSection(&getMonitor(h).mon);
- free(h.__monitor);
- setMonitor(h, null);
- debug(PRINTF) printf("-_d_monitor_destroy(%p)\n", h);
- }
- extern (C) void _d_monitor_lock(Object h)
- {
- debug(PRINTF) printf("+_d_monitor_acquire(%p)\n", h);
- assert(h && h.__monitor && !getMonitor(h).impl);
- EnterCriticalSection(&getMonitor(h).mon);
- debug(PRINTF) printf("-_d_monitor_acquire(%p)\n", h);
- }
- extern (C) void _d_monitor_unlock(Object h)
- {
- debug(PRINTF) printf("+_d_monitor_release(%p)\n", h);
- assert(h && h.__monitor && !getMonitor(h).impl);
- LeaveCriticalSection(&getMonitor(h).mon);
- debug(PRINTF) printf("-_d_monitor_release(%p)\n", h);
- }
- }
- /* =============================== linux ============================ */
- version( USE_PTHREADS )
- {
- // Includes attribute fixes from David Friedman's GDC port
- static __gshared pthread_mutex_t _monitor_critsec;
- static __gshared pthread_mutexattr_t _monitors_attr;
- extern (C) void _STI_monitor_staticctor()
- {
- if (!inited)
- {
- pthread_mutexattr_init(&_monitors_attr);
- pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&_monitor_critsec, &_monitors_attr);
- inited = 1;
- }
- }
- extern (C) void _STD_monitor_staticdtor()
- {
- if (inited)
- {
- inited = 0;
- pthread_mutex_destroy(&_monitor_critsec);
- pthread_mutexattr_destroy(&_monitors_attr);
- }
- }
- extern (C) void _d_monitor_create(Object h)
- {
- /*
- * NOTE: Assume this is only called when h.__monitor is null prior to the
- * call. However, please note that another thread may call this function
- * at the same time, so we can not assert this here. Instead, try and
- * create a lock, and if one already exists then forget about it.
- */
- debug(PRINTF) printf("+_d_monitor_create(%p)\n", h);
- assert(h);
- Monitor *cs;
- pthread_mutex_lock(&_monitor_critsec);
- if (!h.__monitor)
- {
- cs = cast(Monitor *)calloc(Monitor.sizeof, 1);
- assert(cs);
- pthread_mutex_init(&cs.mon, &_monitors_attr);
- setMonitor(h, cs);
- cs.refs = 1;
- cs = null;
- }
- pthread_mutex_unlock(&_monitor_critsec);
- if (cs)
- free(cs);
- debug(PRINTF) printf("-_d_monitor_create(%p)\n", h);
- }
- extern (C) void _d_monitor_destroy(Object h)
- {
- debug(PRINTF) printf("+_d_monitor_destroy(%p)\n", h);
- assert(h && h.__monitor && !getMonitor(h).impl);
- pthread_mutex_destroy(&getMonitor(h).mon);
- free(h.__monitor);
- setMonitor(h, null);
- debug(PRINTF) printf("-_d_monitor_destroy(%p)\n", h);
- }
- extern (C) void _d_monitor_lock(Object h)
- {
- debug(PRINTF) printf("+_d_monitor_acquire(%p)\n", h);
- assert(h && h.__monitor && !getMonitor(h).impl);
- pthread_mutex_lock(&getMonitor(h).mon);
- debug(PRINTF) printf("-_d_monitor_acquire(%p)\n", h);
- }
- extern (C) void _d_monitor_unlock(Object h)
- {
- debug(PRINTF) printf("+_d_monitor_release(%p)\n", h);
- assert(h && h.__monitor && !getMonitor(h).impl);
- pthread_mutex_unlock(&getMonitor(h).mon);
- debug(PRINTF) printf("-_d_monitor_release(%p)\n", h);
- }
- }