Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 2076

Show
Ignore:
Timestamp:
04/19/07 03:16:03 (2 years ago)
Author:
sean
Message:

Made some changes to allow users to override the built-in monitor for objects. Checking still needs to be added to prohibit setting a monitor if one already exists. Tested on Win32 so far. Linux is next.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/lib/compiler/dmd/genobj.d

    r2041 r2076  
    6969 
    7070/** 
    71  * Internal struct pointed to by the hidden .monitor member. 
    72  */ 
    73 struct Monitor 
    74 { 
    75     void delegate(Object)[] delegates; 
    76  
    77     /* More stuff goes here defined by internal/monitor.c */ 
    78 } 
    79  
    80 /** 
    8171 * All D class objects inherit from Object. 
    8272 */ 
     
    126116    } 
    127117 
    128 /+ 
    129     /* ** 
    130      * Call delegate dg, passing this to it, when this object gets destroyed. 
    131      * Use extreme caution, as the list of delegates is stored in a place 
    132      * not known to the gc. Thus, if any objects pointed to by one of these 
    133      * delegates gets freed by the gc, calling the delegate will cause a 
    134      * crash. 
    135      * This is only for use by library developers, as it will need to be 
    136      * redone if weak pointers are added or a moving gc is developed. 
    137      */ 
    138     final void notifyRegister(void delegate(Object) dg) 
    139     { 
    140         debug(PRINTF) printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); 
    141         synchronized (this) 
    142         { 
    143             Monitor* m = cast(Monitor*)(cast(void**)this)[1]; 
    144             foreach (inout x; m.delegates) 
    145             { 
    146                 if (!x || x == dg) 
    147                 {   x = dg; 
    148                     return; 
    149                 } 
    150             } 
    151  
    152             // Increase size of delegates[] 
    153             auto len = m.delegates.length; 
    154             auto startlen = len; 
    155             if (len == 0) 
    156             { 
    157                 len = 4; 
    158                 auto p = calloc((void delegate(Object)).sizeof, len); 
    159                 if (!p) 
    160                     onOutOfMemoryError(); 
    161                 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 
    162             } 
    163             else 
    164             { 
    165                 len += len + 4; 
    166                 auto p = realloc(m.delegates.ptr, (void delegate(Object)).sizeof * len); 
    167                 if (!p) 
    168                     onOutOfMemoryError(); 
    169                 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 
    170                 m.delegates[startlen .. len] = null; 
    171             } 
    172             m.delegates[startlen] = dg; 
    173         } 
    174     } 
    175  
    176     /* ** 
    177      * Remove delegate dg from the notify list. 
    178      * This is only for use by library developers, as it will need to be 
    179      * redone if weak pointers are added or a moving gc is developed. 
    180      */ 
    181     final void notifyUnRegister(void delegate(Object) dg) 
    182     { 
    183         synchronized (this) 
    184         { 
    185             Monitor* m = cast(Monitor*)(cast(void**)this)[1]; 
    186             foreach (inout x; m.delegates) 
    187             { 
    188                 if (x == dg) 
    189                     x = null; 
    190             } 
    191         } 
    192     } 
    193 +/ 
    194 
    195  
    196 extern (C) void _d_notify_release(Object o) 
    197 
    198     debug(PRINTF) printf("_d_notify_release(o = %p)\n", o); 
    199     Monitor* m = cast(Monitor*)(cast(void**)o)[1]; 
    200     if (m.delegates.length) 
    201     { 
    202         auto dgs = m.delegates; 
    203         synchronized (o) 
    204         { 
    205             dgs = m.delegates; 
    206             m.delegates = null; 
    207         } 
    208  
    209         foreach (dg; dgs) 
    210         { 
    211             if (dg) 
    212             {   debug(PRINTF) printf("calling dg = %llx (%p)\n", dg, o); 
    213                 dg(o); 
    214             } 
    215         } 
    216  
    217         free(dgs.ptr); 
     118    interface Monitor 
     119    { 
     120        void lock(); 
     121        void unlock(); 
    218122    } 
    219123} 
     
    1017921enum 
    1018922{ 
    1019     MIctorstart = 1,    // we've started constructing it 
    1020     MIctordone = 2,     // finished construction 
     923    MIctorstart = 1,   // we've started constructing it 
     924    MIctordone   = 2,   // finished construction 
    1021925    MIstandalone = 4,   // module ctor does not depend on other module 
    1022926                        // ctors being done first 
     
    1067971extern (C) int _fatexit(void *); 
    1068972 
    1069 /************************************* 
     973/** 
    1070974 * Initialize the modules. 
    1071975 */ 
     
    11431047} 
    11441048 
    1145  
    1146 /********************************** 
     1049/** 
    11471050 * Destruct the modules. 
    11481051 */ 
     
    11671070} 
    11681071 
    1169 /********************************** 
     1072/** 
    11701073 * Run unit tests. 
    11711074 */ 
     
    11881091    } 
    11891092} 
     1093 
     1094 
     1095//////////////////////////////////////////////////////////////////////////////// 
     1096// Monitor 
     1097//////////////////////////////////////////////////////////////////////////////// 
     1098 
     1099alias Object.Monitor IMonitor; 
     1100 
     1101struct Monitor 
     1102{ 
     1103    IMonitor impl; 
     1104    /* stuff */ 
     1105} 
     1106 
     1107Monitor* getMonitor(Object h) 
     1108{ 
     1109    return cast(Monitor*) (cast(void**) h)[1]; 
     1110} 
     1111 
     1112void setMonitor(Object h, Monitor* m) 
     1113{ 
     1114    (cast(void**) h)[1] = m; 
     1115} 
     1116 
     1117extern (C) void _d_monitor_create(Object); 
     1118extern (C) void _d_monitor_destroy(Object); 
     1119extern (C) void _d_monitor_lock(Object); 
     1120extern (C) int  _d_monitor_unlock(Object); 
     1121 
     1122extern (C) void _d_monitordelete(Object h, bool det) 
     1123{ 
     1124    Monitor* m = getMonitor(h); 
     1125 
     1126    if (m !is null) 
     1127    { 
     1128        IMonitor i = m.impl; 
     1129        if (i is null) 
     1130        { 
     1131            _d_monitor_destroy(h); 
     1132            setMonitor(h, null); 
     1133            return; 
     1134        } 
     1135        if (det && (cast(void*) i) !is (cast(void*) h)) 
     1136            delete i; 
     1137        setMonitor(h, null); 
     1138    } 
     1139} 
     1140 
     1141extern (C) void _d_monitorenter(Object h) 
     1142{ 
     1143    Monitor* m = getMonitor(h); 
     1144 
     1145    if (m is null) 
     1146    { 
     1147        _d_monitor_create(h); 
     1148        m = getMonitor(h); 
     1149    } 
     1150 
     1151    IMonitor i = m.impl; 
     1152 
     1153    if (i is null) 
     1154    { 
     1155        _d_monitor_lock(h); 
     1156        return; 
     1157    } 
     1158    i.lock(); 
     1159} 
     1160 
     1161extern (C) void _d_monitorexit(Object h) 
     1162{ 
     1163    Monitor* m = getMonitor(h); 
     1164    IMonitor i = m.impl; 
     1165 
     1166    if (i is null) 
     1167    { 
     1168        _d_monitor_unlock(h); 
     1169        return; 
     1170    } 
     1171    i.unlock(); 
     1172} 
  • trunk/lib/compiler/dmd/lifetime.d

    r2020 r2076  
    6262    extern (C) void onOutOfMemoryError(); 
    6363 
    64     extern (C) void _d_monitorrelease(Object h); 
     64    extern (C) void _d_monitordelete(Object h, bool det = true); 
    6565 
    6666    enum 
     
    421421                } 
    422422                if ((cast(void**)p)[1]) // if monitor is not null 
    423                     _d_monitorrelease(cast(Object)p); 
     423                    _d_monitordelete(cast(Object)p, det); 
    424424            } 
    425425            catch (Exception e) 
  • trunk/lib/compiler/dmd/mars.h

    r925 r2076  
    9090void _d_monitorenter(Object *h); 
    9191void _d_monitorexit(Object *h); 
    92 void _d_monitorrelease(Object *h); 
    9392 
    9493int _d_isbaseof(ClassInfo *b, ClassInfo *c); 
  • trunk/lib/compiler/dmd/monitor.c

    r1901 r2076  
    3131typedef struct Monitor 
    3232{ 
    33     Array delegates;   // for the notification system 
     33    void* impl; // for user-level monitors 
    3434 
    3535#if _WIN32 
     
    4545 
    4646static volatile int inited; 
    47  
    48 void _d_notify_release(Object *); 
    4947 
    5048/* =============================== Win32 ============================ */ 
     
    7068} 
    7169 
    72 void _d_monitorenter(Object *h) 
    73 
    74     //printf("_d_monitorenter(%p), %p\n", h, h->monitor); 
     70void _d_monitor_create(Object *h) 
     71
     72    /* 
     73     * NOTE: Assume this is only called when h->monitor is null prior to the 
     74     * call.  However, please note that another thread may call this function 
     75     * at the same time, so we can not assert this here.  Instead, try and 
     76     * create a lock, and if one already exists then forget about it. 
     77     */ 
     78 
     79    //printf("+_d_monitor_create(%p)\n", h); 
     80    assert(h); 
     81    Monitor *cs = NULL; 
     82    EnterCriticalSection(&_monitor_critsec); 
    7583    if (!h->monitor) 
    76     {   Monitor *cs; 
    77  
    78     cs = (Monitor *)calloc(sizeof(Monitor), 1); 
    79     assert(cs); 
    80     EnterCriticalSection(&_monitor_critsec); 
    81     if (!h->monitor)    // if, in the meantime, another thread didn't set it 
    82     { 
    83         h->monitor = (void *)cs; 
    84         InitializeCriticalSection(&cs->mon); 
    85         cs = NULL; 
    86     } 
    87     LeaveCriticalSection(&_monitor_critsec); 
    88     if (cs)         // if we didn't use it 
    89         free(cs); 
    90     } 
    91     //printf("-_d_monitorenter(%p)\n", h); 
     84    { 
     85        cs = (Monitor *)calloc(sizeof(Monitor), 1); 
     86        assert(cs); 
     87        InitializeCriticalSection(&cs->mon); 
     88        h->monitor = (void *)cs; 
     89        cs = NULL; 
     90    } 
     91    LeaveCriticalSection(&_monitor_critsec); 
     92    if (cs) 
     93        free(cs); 
     94    //printf("-_d_monitor_create(%p)\n", h); 
     95
     96 
     97void _d_monitor_destroy(Object *h) 
     98
     99    //printf("+_d_monitor_destroy(%p)\n", h); 
     100    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
     101    DeleteCriticalSection(MONPTR(h)); 
     102    free((void *)h->monitor); 
     103    h->monitor = NULL; 
     104    //printf("-_d_monitor_destroy(%p)\n", h); 
     105
     106 
     107int _d_monitor_lock(Object *h) 
     108
     109    //printf("+_d_monitor_acquire(%p)\n", h); 
     110    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    92111    EnterCriticalSection(MONPTR(h)); 
    93     //printf("-_d_monitorenter(%p)\n", h); 
    94 } 
    95  
    96 void _d_monitorexit(Object *h) 
    97 { 
    98     //printf("_d_monitorexit(%p)\n", h); 
    99     assert(h->monitor); 
     112    //printf("-_d_monitor_acquire(%p)\n", h); 
     113} 
     114 
     115void _d_monitor_unlock(Object *h) 
     116{ 
     117    //printf("+_d_monitor_release(%p)\n", h); 
     118    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    100119    LeaveCriticalSection(MONPTR(h)); 
    101 
    102  
    103 /*************************************** 
    104  * Called by garbage collector when Object is free'd. 
    105  */ 
    106  
    107 void _d_monitorrelease(Object *h) 
    108 
    109     if (h->monitor) 
    110     { 
    111     _d_notify_release(h); 
    112  
    113     DeleteCriticalSection(MONPTR(h)); 
    114  
    115     // We can improve this by making a free list of monitors 
    116     free((void *)h->monitor); 
    117  
    118     h->monitor = NULL; 
    119     } 
     120    //printf("-_d_monitor_release(%p)\n", h); 
    120121} 
    121122 
     
    151152} 
    152153 
    153 void _d_monitorenter(Object *h) 
    154 
    155     //printf("_d_monitorenter(%p), %p\n", h, h->monitor); 
     154void _d_monitor_create(Object *h) 
     155
     156    /* 
     157     * NOTE: Assume this is only called when h->monitor is null prior to the 
     158     * call.  However, please note that another thread may call this function 
     159     * at the same time, so we can not assert this here.  Instead, try and 
     160     * create a lock, and if one already exists then forget about it. 
     161     */ 
     162 
     163    //printf("+_d_monitor_create(%p)\n", h); 
     164    assert(h); 
     165    Monitor *cs = NULL; 
     166    pthread_mutex_lock(&_monitor_critsec); 
    156167    if (!h->monitor) 
    157     {   Monitor *cs; 
    158  
    159     cs = (Monitor *)calloc(sizeof(Monitor), 1); 
    160     assert(cs); 
    161     pthread_mutex_lock(&_monitor_critsec); 
    162     if (!h->monitor)    // if, in the meantime, another thread didn't set it 
    163     { 
    164         h->monitor = (void *)cs; 
    165         pthread_mutex_init(&cs->mon, & _monitors_attr); 
    166         cs = NULL; 
    167     } 
    168     pthread_mutex_unlock(&_monitor_critsec); 
    169     if (cs)         // if we didn't use it 
    170         free(cs); 
    171     } 
    172     //printf("-_d_monitorenter(%p)\n", h); 
     168    { 
     169        cs = (Monitor *)calloc(sizeof(Monitor), 1); 
     170        assert(cs); 
     171        pthread_mutex_init(&cs->mon, & _monitors_attr); 
     172        h->monitor = (void *)cs; 
     173        cs = NULL; 
     174    } 
     175    pthread_mutex_unlock(&_monitor_critsec); 
     176    if (cs) 
     177        free(cs); 
     178    //printf("-_d_monitor_create(%p)\n", h); 
     179
     180 
     181void _d_monitor_destroy(Object *h) 
     182
     183    //printf("+_d_monitor_destroy(%p)\n", h); 
     184    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
     185    pthread_mutex_destroy(MONPTR(h)); 
     186    free((void *)h->monitor); 
     187    h->monitor = NULL; 
     188    //printf("-_d_monitor_destroy(%p)\n", h); 
     189
     190 
     191int _d_monitor_lock(Object *h) 
     192
     193    //printf("+_d_monitor_acquire(%p)\n", h); 
     194    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    173195    pthread_mutex_lock(MONPTR(h)); 
    174     //printf("-_d_monitorenter(%p)\n", h); 
    175 } 
    176  
    177 void _d_monitorexit(Object *h) 
    178 { 
    179     //printf("+_d_monitorexit(%p)\n", h); 
    180     assert(h->monitor); 
     196    //printf("-_d_monitor_acquire(%p)\n", h); 
     197} 
     198 
     199void _d_monitor_unlock(Object *h) 
     200{ 
     201    //printf("+_d_monitor_release(%p)\n", h); 
     202    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    181203    pthread_mutex_unlock(MONPTR(h)); 
    182     //printf("-_d_monitorexit(%p)\n", h); 
    183 
    184  
    185 /*************************************** 
    186  * Called by garbage collector when Object is free'd. 
    187  */ 
    188  
    189 void _d_monitorrelease(Object *h) 
    190 
    191     if (h->monitor) 
    192     { 
    193     _d_notify_release(h); 
    194  
    195     pthread_mutex_destroy(MONPTR(h)); 
    196  
    197     // We can improve this by making a free list of monitors 
    198     free((void *)h->monitor); 
    199  
    200     h->monitor = NULL; 
    201     } 
    202 
    203  
    204 #endif 
     204    //printf("-_d_monitor_release(%p)\n", h); 
     205
     206 
     207#endif 
  • trunk/lib/compiler/gdc/genobj.d

    r2041 r2076  
    1010 
    1111/* 
    12  *  Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com 
     12 *  Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com 
    1313 *  Written by Walter Bright 
    1414 * 
     
    4343    import tango.stdc.stdlib; // : calloc, realloc, free; 
    4444    import util.string; 
    45     debug import tango.stdc.stdio; // : printf; 
     45    debug(PRINTF) import tango.stdc.stdio; // : printf; 
    4646 
    4747    extern (C) void onOutOfMemoryError(); 
     48    extern (C) Object _d_newclass(ClassInfo ci); 
    4849} 
    4950 
     
    125126    } 
    126127 
    127 /+ 
    128     /* ** 
    129      * Call delegate dg, passing this to it, when this object gets destroyed. 
    130      * Use extreme caution, as the list of delegates is stored in a place 
    131      * not known to the gc. Thus, if any objects pointed to by one of these 
    132      * delegates gets freed by the gc, calling the delegate will cause a 
    133      * crash. 
    134      * This is only for use by library developers, as it will need to be 
    135      * redone if weak pointers are added or a moving gc is developed. 
    136      */ 
    137     final void notifyRegister(void delegate(Object) dg) 
    138     { 
    139         debug printf("notifyRegister(dg = %llx, o = %p)\n", dg, this); 
    140         synchronized (this) 
    141         { 
    142             Monitor* m = cast(Monitor*)(cast(void**)this)[1]; 
    143             foreach (inout x; m.delegates) 
     128    interface Monitor 
    144129            { 
    145                 if (!x || x == dg) 
    146                 {   x = dg; 
    147                     return; 
    148                 } 
    149             } 
    150  
    151             // Increase size of delegates[] 
    152             auto len = m.delegates.length; 
    153             auto startlen = len; 
    154             if (len == 0) 
    155             { 
    156                 len = 4; 
    157                 auto p = calloc((void delegate(Object)).sizeof, len); 
    158                 if (!p) 
    159                     onOutOfMemoryError(); 
    160                 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 
    161             } 
    162             else 
    163             { 
    164                 len += len + 4; 
    165                 auto p = realloc(m.delegates.ptr, (void delegate(Object)).sizeof * len); 
    166                 if (!p) 
    167                     onOutOfMemoryError(); 
    168                 m.delegates = (cast(void delegate(Object)*)p)[0 .. len]; 
    169                 m.delegates[startlen .. len] = null; 
    170             } 
    171             m.delegates[startlen] = dg; 
    172         } 
    173     } 
    174  
    175     /* ** 
    176      * Remove delegate dg from the notify list. 
    177      * This is only for use by library developers, as it will need to be 
    178      * redone if weak pointers are added or a moving gc is developed. 
    179      */ 
    180     final void notifyUnRegister(void delegate(Object) dg) 
    181     { 
    182         synchronized (this) 
    183         { 
    184             Monitor* m = cast(Monitor*)(cast(void**)this)[1]; 
    185             foreach (inout x; m.delegates) 
    186             { 
    187                 if (x == dg) 
    188                     x = null; 
    189             } 
    190         } 
    191     } 
    192 +/ 
    193 
    194  
    195 extern (C) void _d_notify_release(Object o) 
    196 
    197     debug printf("_d_notify_release(o = %p)\n", o); 
    198     Monitor* m = cast(Monitor*)(cast(void**)o)[1]; 
    199     if (m.delegates.length) 
    200     { 
    201         auto dgs = m.delegates; 
    202         synchronized (o) 
    203         { 
    204             dgs = m.delegates; 
    205             m.delegates = null; 
    206         } 
    207  
    208         foreach (dg; dgs) 
    209         { 
    210             if (dg) 
    211             {   debug printf("calling dg = %llx (%p)\n", dg, o); 
    212                 dg(o); 
    213             } 
    214         } 
    215  
    216         free(dgs.ptr); 
    217     } 
    218 
    219  
     130        void lock(); 
     131        void unlock(); 
     132        } 
     133    } 
    220134 
    221135/** 
     
    813727        assert(p); 
    814728        if (xtoHash) 
    815         {   debug printf("getHash() using xtoHash\n"); 
     729        {   debug(PRINTF) printf("getHash() using xtoHash\n"); 
    816730            h = (*xtoHash)(p); 
    817731        } 
    818732        else 
    819733        { 
    820             debug printf("getHash() using default hash\n"); 
     734            debug(PRINTF) printf("getHash() using default hash\n"); 
    821735            // A sorry hash algorithm. 
    822736            // Should use the one for strings. 
     
    988902 
    989903 
     904//////////////////////////////////////////////////////////////////////////////// 
     905// ModuleInfo 
     906//////////////////////////////////////////////////////////////////////////////// 
     907 
    990908 
    991909enum 
     
    1047965extern (C) int _fatexit(void *); 
    1048966 
    1049 /************************************* 
     967/** 
    1050968 * Initialize the modules. 
    1051969 */ 
     
    1053971extern (C) void _moduleCtor() 
    1054972{ 
    1055     debug printf("_moduleCtor()\n"); 
     973    debug(PRINTF) printf("_moduleCtor()\n"); 
    1056974    version (ModRefStyle) 
    1057975    { 
     
    1076994 
    1077995    _moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length]; 
    1078     debug printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); 
     996    debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors); 
    1079997    _moduleCtor2(_moduleinfo_array, 0); 
    1080998} 
     
    10821000void _moduleCtor2(ModuleInfo[] mi, int skip) 
    10831001{ 
    1084     debug printf("_moduleCtor2(): %d modules\n", mi.length); 
     1002    debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length); 
    10851003    for (uint i = 0; i < mi.length; i++) 
    10861004    { 
    10871005        ModuleInfo m = mi[i]; 
    10881006 
    1089         debug printf("\tmodule[%d] = '%p'\n", i, m); 
     1007        debug(PRINTF) printf("\tmodule[%d] = '%p'\n", i, m); 
    10901008        if (!m) 
    10911009            continue; 
    1092         debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); 
     1010        debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name); 
    10931011        if (m.flags & MIctordone) 
    10941012            continue; 
    1095         debug printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m); 
     1013        debug(PRINTF) printf("\tmodule[%d] = '%.*s', m = x%x\n", i, m.name, m); 
    10961014 
    10971015        if (m.ctor || m.dtor) 
     
    11231041} 
    11241042 
    1125  
    1126 /********************************** 
     1043/** 
    11271044 * Destruct the modules. 
    11281045 */ 
     
    11331050extern (C) void _moduleDtor() 
    11341051{ 
    1135     debug printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i); 
     1052    debug(PRINTF) printf("_moduleDtor(): %d modules\n", _moduleinfo_dtors_i); 
    11361053    for (uint i = _moduleinfo_dtors_i; i-- != 0;) 
    11371054    { 
    11381055        ModuleInfo m = _moduleinfo_dtors[i]; 
    11391056 
    1140         debug printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); 
     1057        debug(PRINTF) printf("\tmodule[%d] = '%.*s', x%x\n", i, m.name, m); 
    11411058        if (m.dtor) 
    11421059        { 
     
    11441061        } 
    11451062    } 
    1146     debug printf("_moduleDtor() done\n"); 
    1147 } 
    1148  
    1149 /********************************** 
     1063    debug(PRINTF) printf("_moduleDtor() done\n"); 
     1064} 
     1065 
     1066/** 
    11501067 * Run unit tests. 
    11511068 */ 
     
    11531070extern (C) void _moduleUnitTests() 
    11541071{ 
    1155     debug printf("_moduleUnitTests()\n"); 
     1072    debug(PRINTF) printf("_moduleUnitTests()\n"); 
    11561073    for (uint i = 0; i < _moduleinfo_array.length; i++) 
    11571074    { 
     
    11611078            continue; 
    11621079 
    1163         debug printf("\tmodule[%d] = '%.*s'\n", i, m.name); 
     1080        debug(PRINTF) printf("\tmodule[%d] = '%.*s'\n", i, m.name); 
    11641081        if (m.unitTest) 
    11651082        { 
     
    11681085    } 
    11691086} 
     1087 
     1088//////////////////////////////////////////////////////////////////////////////// 
     1089// Monitor 
     1090//////////////////////////////////////////////////////////////////////////////// 
     1091 
     1092alias Object.Monitor IMonitor; 
     1093 
     1094struct Monitor 
     1095{ 
     1096    IMonitor impl; 
     1097    /* stuff */ 
     1098} 
     1099 
     1100Monitor* getMonitor(Object h) 
     1101{ 
     1102    return cast(Monitor*) (cast(void**) h)[1]; 
     1103} 
     1104 
     1105void setMonitor(Object h, Monitor* m) 
     1106{ 
     1107    (cast(void**) h)[1] = m; 
     1108} 
     1109 
     1110extern (C) void _d_monitor_create(Object); 
     1111extern (C) void _d_monitor_destroy(Object); 
     1112extern (C) void _d_monitor_lock(Object); 
     1113extern (C) int  _d_monitor_unlock(Object); 
     1114 
     1115extern (C) void _d_monitordelete(Object h, bool det) 
     1116{ 
     1117    Monitor* m = getMonitor(h); 
     1118 
     1119    if (m !is null) 
     1120    { 
     1121        IMonitor i = m.impl; 
     1122        if (i is null) 
     1123        { 
     1124            _d_monitor_destroy(h); 
     1125            setMonitor(h, null); 
     1126            return; 
     1127        } 
     1128        if (det && (cast(void*) i) !is (cast(void*) h)) 
     1129            delete i; 
     1130        setMonitor(h, null); 
     1131    } 
     1132} 
     1133 
     1134extern (C) void _d_monitorenter(Object h) 
     1135{ 
     1136    Monitor* m = getMonitor(h); 
     1137 
     1138    if (m is null) 
     1139    { 
     1140        _d_monitor_create(h); 
     1141        m = getMonitor(h); 
     1142    } 
     1143 
     1144    IMonitor i = m.impl; 
     1145 
     1146    if (i is null) 
     1147    { 
     1148        _d_monitor_lock(h); 
     1149        return; 
     1150    } 
     1151    i.lock(); 
     1152} 
     1153 
     1154extern (C) void _d_monitorexit(Object h) 
     1155{ 
     1156    Monitor* m = getMonitor(h); 
     1157    IMonitor i = m.impl; 
     1158 
     1159    if (i is null) 
     1160    { 
     1161        _d_monitor_unlock(h); 
     1162        return; 
     1163    } 
     1164    i.unlock(); 
     1165} 
  • trunk/lib/compiler/gdc/lifetime.d

    r2021 r2076  
    6262    extern (C) void onOutOfMemoryError(); 
    6363 
    64     extern (C) void _d_monitorrelease(Object h); 
     64    extern (C) void _d_monitordelete(Object h, bool det = true); 
    6565 
    6666    enum 
     
    410410                } 
    411411                if ((cast(void**)p)[1]) // if monitor is not null 
    412                     _d_monitorrelease(cast(Object)p); 
     412                    _d_monitordelete(cast(Object)p, det); 
    413413            } 
    414414            catch (Exception e) 
  • trunk/lib/compiler/gdc/mars.h

    r1856 r2076  
    9191void _d_monitorenter(Object *h); 
    9292void _d_monitorexit(Object *h); 
    93 void _d_monitorrelease(Object *h); 
    9493 
    9594int _d_isbaseof(ClassInfo *b, ClassInfo *c); 
  • trunk/lib/compiler/gdc/monitor.c

    r1901 r2076  
    4040typedef struct Monitor 
    4141{ 
    42     Array delegates;   // for the notification system 
     42    void* impl; // for user-level monitors 
    4343 
    4444#if _WIN32 
     
    5454 
    5555static volatile int inited; 
    56  
    57 void _d_notify_release(Object *); 
    5856 
    5957/* =============================== Win32 ============================ */ 
     
    7977} 
    8078 
    81 void _d_monitorenter(Object *h) 
    82 
    83     //printf("_d_monitorenter(%p), %p\n", h, h->monitor); 
     79void _d_monitor_create(Object *h) 
     80
     81    /* 
     82     * NOTE: Assume this is only called when h->monitor is null prior to the 
     83     * call.  However, please note that another thread may call this function 
     84     * at the same time, so we can not assert this here.  Instead, try and 
     85     * create a lock, and if one already exists then forget about it. 
     86     */ 
     87 
     88    //printf("+_d_monitor_create(%p)\n", h); 
     89    assert(h); 
     90    Monitor *cs = NULL; 
     91    EnterCriticalSection(&_monitor_critsec); 
    8492    if (!h->monitor) 
    85     {   Monitor *cs; 
    86  
    87     cs = (Monitor *)calloc(sizeof(Monitor), 1); 
    88     assert(cs); 
    89     EnterCriticalSection(&_monitor_critsec); 
    90     if (!h->monitor)    // if, in the meantime, another thread didn't set it 
    91     { 
    92         h->monitor = (void *)cs; 
    93         InitializeCriticalSection(&cs->mon); 
    94         cs = NULL; 
    95     } 
    96     LeaveCriticalSection(&_monitor_critsec); 
    97     if (cs)         // if we didn't use it 
    98         free(cs); 
    99     } 
    100     //printf("-_d_monitorenter(%p)\n", h); 
     93    { 
     94        cs = (Monitor *)calloc(sizeof(Monitor), 1); 
     95        assert(cs); 
     96        InitializeCriticalSection(&cs->mon); 
     97        h->monitor = (void *)cs; 
     98        cs = NULL; 
     99    } 
     100    LeaveCriticalSection(&_monitor_critsec); 
     101    if (cs) 
     102        free(cs); 
     103    //printf("-_d_monitor_create(%p)\n", h); 
     104
     105 
     106void _d_monitor_destroy(Object *h) 
     107
     108    //printf("+_d_monitor_destroy(%p)\n", h); 
     109    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
     110    DeleteCriticalSection(MONPTR(h)); 
     111    free((void *)h->monitor); 
     112    h->monitor = NULL; 
     113    //printf("-_d_monitor_destroy(%p)\n", h); 
     114
     115 
     116int _d_monitor_lock(Object *h) 
     117
     118    //printf("+_d_monitor_acquire(%p)\n", h); 
     119    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    101120    EnterCriticalSection(MONPTR(h)); 
    102     //printf("-_d_monitorenter(%p)\n", h); 
    103 } 
    104  
    105 void _d_monitorexit(Object *h) 
    106 { 
    107     //printf("_d_monitorexit(%p)\n", h); 
    108     assert(h->monitor); 
     121    //printf("-_d_monitor_acquire(%p)\n", h); 
     122} 
     123 
     124void _d_monitor_unlock(Object *h) 
     125{ 
     126    //printf("+_d_monitor_release(%p)\n", h); 
     127    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    109128    LeaveCriticalSection(MONPTR(h)); 
    110 
    111  
    112 /*************************************** 
    113  * Called by garbage collector when Object is free'd. 
    114  */ 
    115  
    116 void _d_monitorrelease(Object *h) 
    117 
    118     if (h->monitor) 
    119     { 
    120     _d_notify_release(h); 
    121  
    122     DeleteCriticalSection(MONPTR(h)); 
    123  
    124     // We can improve this by making a free list of monitors 
    125     free((void *)h->monitor); 
    126  
    127     h->monitor = NULL; 
    128     } 
     129    //printf("-_d_monitor_release(%p)\n", h); 
    129130} 
    130131 
     
    166167} 
    167168 
    168 void _d_monitorenter(Object *h) 
    169 
    170     //printf("_d_monitorenter(%p), %p\n", h, h->monitor); 
     169void _d_monitor_create(Object *h) 
     170
     171    /* 
     172     * NOTE: Assume this is only called when h->monitor is null prior to the 
     173     * call.  However, please note that another thread may call this function 
     174     * at the same time, so we can not assert this here.  Instead, try and 
     175     * create a lock, and if one already exists then forget about it. 
     176     */ 
     177 
     178    //printf("+_d_monitor_create(%p)\n", h); 
     179    assert(h); 
     180    Monitor *cs = NULL; 
     181    pthread_mutex_lock(&_monitor_critsec); 
    171182    if (!h->monitor) 
    172     {   Monitor *cs; 
    173  
    174     cs = (Monitor *)calloc(sizeof(Monitor), 1); 
    175     assert(cs); 
    176     pthread_mutex_lock(&_monitor_critsec); 
    177     if (!h->monitor)    // if, in the meantime, another thread didn't set it 
    178     { 
    179         h->monitor = (void *)cs; 
     183    { 
     184        cs = (Monitor *)calloc(sizeof(Monitor), 1); 
     185        assert(cs); 
    180186#ifndef PTHREAD_MUTEX_ALREADY_RECURSIVE 
    181187        pthread_mutex_init(&cs->mon, & _monitors_attr); 
     
    183189        pthread_mutex_init(&cs->mon, NULL); 
    184190#endif 
    185         cs = NULL; 
    186     } 
    187     pthread_mutex_unlock(&_monitor_critsec); 
    188     if (cs)         // if we didn't use it 
    189         free(cs); 
    190     } 
    191     //printf("-_d_monitorenter(%p)\n", h); 
     191        h->monitor = (void *)cs; 
     192        cs = NULL; 
     193    } 
     194    pthread_mutex_unlock(&_monitor_critsec); 
     195    if (cs) 
     196        free(cs); 
     197    //printf("-_d_monitor_create(%p)\n", h); 
     198
     199 
     200void _d_monitor_destroy(Object *h) 
     201
     202    //printf("+_d_monitor_destroy(%p)\n", h); 
     203    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
     204    pthread_mutex_destroy(MONPTR(h)); 
     205    free((void *)h->monitor); 
     206    h->monitor = NULL; 
     207    //printf("-_d_monitor_destroy(%p)\n", h); 
     208
     209 
     210int _d_monitor_lock(Object *h) 
     211
     212    //printf("+_d_monitor_acquire(%p)\n", h); 
     213    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    192214    pthread_mutex_lock(MONPTR(h)); 
    193     //printf("-_d_monitorenter(%p)\n", h); 
    194 } 
    195  
    196 void _d_monitorexit(Object *h) 
    197 { 
    198     //printf("+_d_monitorexit(%p)\n", h); 
    199     assert(h->monitor); 
     215    //printf("-_d_monitor_acquire(%p)\n", h); 
     216} 
     217 
     218void _d_monitor_unlock(Object *h) 
     219{ 
     220    //printf("+_d_monitor_release(%p)\n", h); 
     221    assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); 
    200222    pthread_mutex_unlock(MONPTR(h)); 
    201     //printf("-_d_monitorexit(%p)\n", h); 
    202 
    203  
    204 /*************************************** 
    205  * Called by garbage collector when Object is free'd. 
    206  */ 
    207  
    208 void _d_monitorrelease(Object *h) 
    209 
    210     if (h->monitor) 
    211     { 
    212     _d_notify_release(h); 
    213  
    214     pthread_mutex_destroy(MONPTR(h)); 
    215  
    216     // We can improve this by making a free list of monitors 
    217     free((void *)h->monitor); 
    218  
    219     h->monitor = NULL; 
    220     } 
    221 
    222  
    223 #endif 
     223    //printf("-_d_monitor_release(%p)\n", h); 
     224
     225 
     226#endif 
  • trunk/object.di

    r1976 r2076  
    1818    } 
    1919 
    20     //final void notifyRegister(void delegate(Object) dg); 
    21     //final void notifyUnRegister(void delegate(Object) dg); 
     20    interface Monitor 
     21    { 
     22        void lock(); 
     23        void unlock(); 
     24    } 
    2225} 
    2326