Changeset 325

Show
Ignore:
Timestamp:
07/07/10 17:13:26 (2 years ago)
Author:
sean
Message:

Added setSameMutex. The current implementation locks the mutex to operate on a refcount, which isn't terribly optimal. I think I'm going to add a Refcount struct to core.atomic to take care of this more efficiently.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/import/object.di

    r295 r325  
    4242bool opEquals(Object lhs, Object rhs); 
    4343//bool opEquals(TypeInfo lhs, TypeInfo rhs); 
     44 
     45void setSameMutex(shared Object ownee, shared Object owner); 
    4446 
    4547struct Interface 
  • trunk/src/object_.d

    r297 r325  
    19341934    /* internal */ 
    19351935    DEvent[] devt; 
     1936    size_t   refs; 
    19361937    /* stuff */ 
    19371938} 
     
    19391940Monitor* getMonitor(Object h) 
    19401941{ 
    1941     return cast(Monitor*) (cast(void**) h)[1]
     1942    return cast(Monitor*) h.__monitor
    19421943} 
    19431944 
    19441945void setMonitor(Object h, Monitor* m) 
    19451946{ 
    1946     (cast(void**) h)[1] = m; 
     1947    h.__monitor = m; 
     1948
     1949 
     1950void setSameMutex(shared Object ownee, shared Object owner) 
     1951in 
     1952
     1953    assert(ownee.__monitor is null); 
     1954
     1955body 
     1956
     1957    auto m = cast(shared(Monitor)*) owner.__monitor; 
     1958 
     1959    if (m is null) 
     1960    { 
     1961        _d_monitor_create(cast(Object) owner); 
     1962        m = cast(shared(Monitor)*) owner.__monitor; 
     1963    } 
     1964     
     1965    auto i = m.impl; 
     1966    if (i is null) 
     1967    { 
     1968        _d_monitor_lock(cast(Object) owner); 
     1969        m.refs++; 
     1970        _d_monitor_unlock(cast(Object) owner); 
     1971        ownee.__monitor = owner.__monitor; 
     1972        return; 
     1973    } 
     1974    // If m.impl is set (ie. if this is a user-created monitor), assume 
     1975    // the monitor is garbage collected and simply copy the reference. 
     1976    ownee.__monitor = owner.__monitor; 
    19471977} 
    19481978 
     
    19541984extern (C) void _d_monitordelete(Object h, bool det) 
    19551985{ 
     1986    // det is true when the object is being destroyed deterministically (ie. 
     1987    // when it is explicitly deleted or is a scope object whose time is up). 
    19561988    Monitor* m = getMonitor(h); 
    19571989 
     
    19611993        if (i is null) 
    19621994        { 
    1963             _d_monitor_devt(m, h); 
    1964             _d_monitor_destroy(h); 
    1965             setMonitor(h, null); 
     1995            _d_monitor_lock(h); 
     1996            auto refs = --m.refs; 
     1997            _d_monitor_unlock(h); 
     1998            if (!refs) 
     1999            { 
     2000                _d_monitor_devt(m, h); 
     2001                _d_monitor_destroy(h); 
     2002                setMonitor(h, null); 
     2003            } 
    19662004            return; 
    19672005        } 
     2006        // NOTE: Since a monitor can be shared via setSameMutex it isn't safe 
     2007        //       to explicitly delete user-created monitors--there's no 
     2008        //       refcount and it may have multiple owners. 
     2009        /+ 
    19682010        if (det && (cast(void*) i) !is (cast(void*) h)) 
    19692011            delete i; 
     2012        +/ 
    19702013        setMonitor(h, null); 
    19712014    } 
  • trunk/src/rt/monitor.c

    r323 r325  
    3434typedef struct Monitor 
    3535{ 
    36     void* impl; // for user-level monitors 
    37     Array devt; // for internal monitors 
     36    void*  impl; // for user-level monitors 
     37    Array  devt; // for internal monitors 
     38    size_t refs; // reference count 
    3839 
    3940#if _WIN32 
     
    9192        InitializeCriticalSection(&cs->mon); 
    9293        h->monitor = (void *)cs; 
     94        cs->refs = 1; 
    9395        cs = NULL; 
    9496    } 
     
    179181        pthread_mutex_init(&cs->mon, & _monitors_attr); 
    180182        h->monitor = (void *)cs; 
     183        cs->refs = 1; 
    181184        cs = NULL; 
    182185    }