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

Changeset 2016

Show
Ignore:
Timestamp:
04/10/07 17:09:15 (2 years ago)
Author:
jcomellas
Message:

* Added ProcessSemaphore? class and tests in the tango.util.locks.Semaphore module.
* Fixed usage of DDOC macros.
* Removed scope attribute for Logger instances.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/example/locks/barrier.d

    r1901 r2016  
    2929    debug (barrier) 
    3030    { 
    31         scope Logger log = Log.getLogger("barrier"); 
     31        Logger log = Log.getLogger("barrier"); 
    3232 
    3333        log.addAppender(new ConsoleAppender(new DateLayout())); 
  • trunk/example/locks/condition.d

    r2010 r2016  
    2222    debug (condition) 
    2323    { 
    24         scope Logger log = Log.getLogger("condition"); 
     24        Logger log = Log.getLogger("condition"); 
    2525 
    2626        log.addAppender(new ConsoleAppender(new DateLayout())); 
  • trunk/example/locks/mutex.d

    r1901 r2016  
    2525    debug (mutex) 
    2626    { 
    27         scope Logger log = Log.getLogger("mutex"); 
     27        Logger log = Log.getLogger("mutex"); 
    2828 
    2929        log.addAppender(new ConsoleAppender(new DateLayout())); 
  • trunk/example/locks/readwritemutex.d

    r2010 r2016  
    3030    debug (readwritemutex) 
    3131    { 
    32         scope Logger log = Log.getLogger("readwritemutex"); 
     32        Logger log = Log.getLogger("readwritemutex"); 
    3333 
    3434        log.addAppender(new ConsoleAppender(new DateLayout())); 
  • trunk/example/locks/semaphore.d

    r2010 r2016  
    1010private import tango.util.locks.Mutex; 
    1111private import tango.util.locks.LockException; 
     12private import tango.core.Exception; 
    1213private import tango.core.Thread; 
    13 private import tango.io.Stdout; 
     14private import tango.io.Console; 
     15private import tango.text.stream.LineIterator; 
    1416private import tango.text.convert.Integer; 
     17private import tango.sys.Process; 
     18 
    1519debug (semaphore) 
    1620{ 
     
    2024} 
    2125 
     26const char[] SemaphoreName = "TestProcessSemaphore"; 
     27 
    2228 
    2329/** 
    2430 * Example program for the tango.util.locks.Barrier module. 
    2531 */ 
    26 void main(char[][] args) 
     32int main(char[][] args) 
     33
     34    if (args.length == 1) 
     35    { 
     36        debug (semaphore) 
     37        { 
     38            Logger log = Log.getLogger("semaphore"); 
     39 
     40            log.addAppender(new ConsoleAppender(new DateLayout())); 
     41 
     42            log.info("Semaphore test"); 
     43        } 
     44 
     45        testSemaphore(); 
     46        testProcessSemaphore(args[0]); 
     47 
     48        return 0; 
     49    } 
     50    else 
     51    { 
     52        return testSecondProcessSemaphore(); 
     53    } 
     54
     55 
     56/** 
     57 * Test for single-process (multi-threaded) semaphores. 
     58 */ 
     59void testSemaphore() 
    2760{ 
    2861    const uint MaxThreadCount   = 10; 
    29  
    30     debug (semaphore) 
    31     { 
    32         scope Logger log = Log.getLogger("semaphore"); 
    33  
    34         log.addAppender(new ConsoleAppender(new DateLayout())); 
    35  
    36         log.info("Semaphore test"); 
    37     } 
    3862 
    3963    // Semaphore used in the tests.  Start it "locked" (i.e., its initial 
     
    4872        debug (semaphore) 
    4973        { 
    50             scope Logger log = Log.getLogger("semaphore." ~ Thread.getThis().name()); 
     74            Logger log = Log.getLogger("semaphore.single." ~ Thread.getThis().name()); 
    5175 
    5276            log.trace("Starting thread"); 
     
    118142        catch (LockException e) 
    119143        { 
    120             Stderr.formatln("Lock exception caught in Semaphore test thread {0}:\n{1}\n", 
    121                             Thread.getThis().name, e.toUtf8())
     144            Cerr("Lock exception caught in Semaphore test thread " ~ Thread.getThis().name ~ 
     145                 ":\n" ~ e.toUtf8()).newline
    122146        } 
    123147        catch (Exception e) 
    124148        { 
    125             Stderr.formatln("Unexpected exception caught in Semaphore test thread {0}:\n{1}\n", 
    126                             Thread.getThis().name, e.toUtf8()); 
    127         } 
     149            Cerr("Unexpected exception caught in Semaphore test thread " ~ Thread.getThis().name ~ 
     150                 ":\n" ~ e.toUtf8()).newline; 
     151        } 
     152    } 
     153 
     154    debug (semaphore) 
     155    { 
     156        Logger log = Log.getLogger("semaphore.single"); 
    128157    } 
    129158 
     
    135164    { 
    136165        thread = new Thread(&semaphoreTestThread); 
    137         thread.name = "thread-" ~ format(tmp, i); 
     166        thread.name = "thread-" ~ tango.text.convert.Integer.format(tmp, i); 
    138167 
    139168        group.add(thread); 
     
    167196    } 
    168197} 
     198 
     199/** 
     200 * Test for multi-process semaphores: this test works by creating a copy of 
     201 * this process that tries to acquire the ProcessSemaphore that was created 
     202 * in this function. If everything works as expected, the attempt should fail, 
     203 * as the count of the semaphore is set to 1. 
     204 */ 
     205void testProcessSemaphore(char[] programName) 
     206{ 
     207    bool success = false; 
     208 
     209    debug (semaphore) 
     210    { 
     211        Logger log = Log.getLogger("semaphore.multi"); 
     212        Logger childLog = Log.getLogger("semaphore.multi.child"); 
     213 
     214        log.info("ProcessSemaphore test"); 
     215    } 
     216 
     217    try 
     218    { 
     219        scope ProcessSemaphore sem = new ProcessSemaphore(SemaphoreName, 1); 
     220        Process proc = new Process(programName, "2"); 
     221 
     222        log.trace("Created ProcessSemaphore('" ~ SemaphoreName ~ "')'"); 
     223 
     224        sem.acquire(); 
     225        debug (semaphore) 
     226            log.trace("Acquired semaphore in main process"); 
     227 
     228        debug (semaphore) 
     229            log.trace("Executing child test process: " ~ proc.toUtf8()); 
     230        proc.execute(); 
     231 
     232        debug (semaphore) 
     233        { 
     234            foreach (line; new LineIterator!(char)(proc.stdout)) 
     235            { 
     236                childLog.trace(line); 
     237            } 
     238        } 
     239        foreach (line; new LineIterator!(char)(proc.stderr)) 
     240        { 
     241            Cerr(line).newline; 
     242        } 
     243 
     244        debug (semaphore) 
     245            log.trace("Waiting for child process to finish"); 
     246        auto result = proc.wait(); 
     247 
     248        success = (result.reason == Process.Result.Exit && result.status == 2); 
     249 
     250        debug (semaphore) 
     251            log.trace("Releasing semaphore in main process"); 
     252        sem.release(); 
     253    } 
     254    catch (LockException e) 
     255    { 
     256        Cerr("Lock exception caught in ProcessSemaphore main test process:\n" ~ e.toUtf8()).newline; 
     257    } 
     258    catch (ProcessException e) 
     259    { 
     260        Cerr("Process exception caught in ProcessSemaphore main test process:\n" ~ e.toUtf8()).newline; 
     261    } 
     262    catch (Exception e) 
     263    { 
     264        Cerr("Unexpected exception caught in ProcessSemaphore main test process:\n" ~ e.toUtf8()).newline; 
     265    } 
     266 
     267    if (success) 
     268    { 
     269        debug (semaphore) 
     270            log.info("The ProcessSemaphore test was successful"); 
     271    } 
     272    else 
     273    { 
     274        debug (semaphore) 
     275        { 
     276            log.error("The multi-process semaphore is not working"); 
     277            assert(false); 
     278        } 
     279        else 
     280        { 
     281            assert(false, "The multi-process semaphore is not working"); 
     282        } 
     283    } 
     284} 
     285 
     286/** 
     287 * Test for multi-process semaphores (second process). 
     288 */ 
     289int testSecondProcessSemaphore() 
     290{ 
     291    int rc = 0; 
     292 
     293    debug (semaphore) 
     294    { 
     295        Cout("Starting child process\n"); 
     296    } 
     297 
     298    try 
     299    { 
     300        scope ProcessSemaphore sem = new ProcessSemaphore(SemaphoreName); 
     301        bool success; 
     302 
     303        success = !sem.tryAcquire(); 
     304        if (success) 
     305        { 
     306            debug (semaphore) 
     307                Cout("Tried to acquire semaphore in child process and failed: OK\n"); 
     308            rc = 2; 
     309        } 
     310        else 
     311        { 
     312            debug (semaphore) 
     313            { 
     314                Cout("Acquired semaphore in child process: this should not have happened\n"); 
     315                Cout("Releasing semaphore in child process\n"); 
     316            } 
     317            sem.release(); 
     318            rc = 1; 
     319        } 
     320    } 
     321    catch (LockException e) 
     322    { 
     323        Cerr("Lock exception caught in ProcessSemaphore child test process:\n" ~ e.toUtf8()).newline; 
     324    } 
     325    catch (ProcessException e) 
     326    { 
     327        Cerr("Process exception caught in ProcessSemaphore child test process:\n" ~ e.toUtf8()).newline; 
     328    } 
     329    catch (Exception e) 
     330    { 
     331        Cerr("Unexpected exception caught in ProcessSemaphore child test process:\n" ~ e.toUtf8()).newline; 
     332    } 
     333 
     334    debug (semaphore) 
     335        Cout("Leaving child process\n"); 
     336 
     337    return rc; 
     338} 
  • trunk/example/networking/selector.d

    r1674 r2016  
    4646int main(char[][] args) 
    4747{ 
    48     scope Logger    log     = Log.getLogger("selector"); 
     48    Logger          log     = Log.getLogger("selector"); 
    4949    Sprint!(char)   sprint  = new Sprint!(char)(256); 
    5050 
  • trunk/tango/util/locks/Barrier.d

    r2010 r2016  
    2222     * This class allows $(D_PARAM count) number of threads to synchronize 
    2323     * their completion of (one round of) a task, which is known as "barrier 
    24      * synchronization". After all the threads call $(D_CODE wait()) on the  
    25      * barrier they are all atomically released and can begin a new round. 
     24     * synchronization". After all the threads call wait() on the barrier they 
     25     * are all atomically released and can begin a new round. 
    2626     */ 
    2727    public class Barrier 
     
    6262        /** 
    6363         * Block the caller until all $(D_PARAM count) threads have called 
    64          * $(D_CODE Barrier.wait()) and then allow all the caller threads to  
    65          * continue in parallel. 
     64         * wait() and then allow all the caller threads to continue in 
     65         * parallel. 
    6666         */ 
    6767        public void wait() 
     
    7777        /** 
    7878         * Check the $(D_PARAM errorCode) argument against possible values 
    79          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    80          * description of the error. 
     79         * of SysError.lastCode() and throw an exception with the description 
     80         * of the error. 
    8181         * 
    8282         * Params: 
     
    129129     * This class allows $(D_PARAM count) number of threads to synchronize 
    130130     * their completion of (one round of) a task, which is known as "barrier 
    131      * synchronization". After all the threads call $(D_CODE wait()) on the 
    132      * barrier they are all atomically released and can begin a new round. 
     131     * synchronization". After all the threads call wait() on the barrier they 
     132     * are all atomically released and can begin a new round. 
    133133     * 
    134134     * Remarks: 
     
    169169         * efficiently solves the problem of what to do if all the first 
    170170         * generation waiters don't leave the barrier before one of the 
    171          * threads calls $(D_CODE wait()) again (i.e., starts up the next  
    172          * generation barrier). 
     171         * threads calls wait() again (i.e., starts up the next  generation 
     172         * barrier). 
    173173         */ 
    174174        SubBarrier[2] _subBarrier; 
     
    203203        /** 
    204204         * Block the caller until all $(D_PARAM count) threads have called 
    205          * $(D_CODE Barrier.wait()) and then allow all the caller threads to  
    206          * continue in parallel. 
     205         * wait() and then allow all the caller threads to  continue in 
     206         * parallel. 
    207207         */ 
    208208        public void wait() 
  • trunk/tango/util/locks/Condition.d

    r2010 r2016  
    2222 * condition under the protection of a mutual exclusion lock (mutex) until 
    2323 * the condition is satisfied. That is, the mutex must have been held by 
    24  * the thread before calling $(D_CODE wait()) or $(D_CODE notify()) / 
    25  * $(D_CODE notifyAll()) on the condition. If the condition is false, a 
    26  * thread blocks on a condition variable and atomically releases the mutex 
    27  * that is waiting for the condition to change. If another thread changes 
    28  * the condition, it may wake up waiting threads by signaling the associated 
    29  * condition variable. The waiting threads, upon awakening, reacquire the 
    30  * mutex and re-evaluate the condition. 
     24 * the thread before calling wait() or notify()/notifyAll() on the condition. 
     25 * If the condition is false, a thread blocks on a condition variable and 
     26 * atomically releases the mutex that is waiting for the condition to change. 
     27 * If another thread changes the condition, it may wake up waiting threads by 
     28 * signaling the associated condition variable. The waiting threads, upon 
     29 * awakening, reacquire the mutex and re-evaluate the condition. 
    3130 * 
    3231 * Remarks: 
    33  * On POSIX-compatible platforms the $(D_CODE Condition) is implemented using a 
    34  * $(D_CODE pthread_cond_t) from the pthread API. The Windows API (before 
    35  * Windows Vista) does not provide a native condition variable, so it is 
    36  * emulated with a mutex, a semaphore and an event. The Windows condition 
    37  * variable emulation is based on the ACE_Condition template class from the 
    38  * $(LINK2 http://www.cs.wustl.edu/~schmidt/ACE.html ACE framework). 
     32 * On POSIX-compatible platforms the Condition is implemented using a 
     33 * pthread_cond_t from the pthread API. The Windows API (before Windows Vista) 
     34 * does not provide a native condition variable, so it is emulated with a 
     35 * mutex, a semaphore and an event. The Windows condition variable emulation 
     36 * is based on the ACE_Condition template class from the 
     37 * $(LINK2 http://www.cs.wustl.edu/~schmidt/ACE.html, ACE framework). 
    3938 * 
    4039 * Examples: 
     
    190189        /** 
    191190         * Block on the condition, or until the specified (relative) amount 
    192          * of time has passed. If ($D_PARAM timeout) == $(D_CODE Interval.max) 
     191         * of time has passed. If ($D_PARAM timeout) is equal to Interval.max 
    193192         * there is no timeout. 
    194193         * 
     
    233232        /** 
    234233         * Check the $(D_PARAM errorCode) argument against possible values 
    235          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    236          * description of the error. 
     234         * of SysError.lastCode() and throw an exception with the description 
     235         * of the error. 
    237236         * 
    238237         * Params: 
     
    475474        /** 
    476475         * Block on the condition, or until the specified (relative) amount 
    477          * of time has passed. If $(D_PARAM timeout) == $(D_CODE Interval.max) 
     476         * of time has passed. If $(D_PARAM timeout) is equal to Interval.max 
    478477         * there is no timeout. 
    479478         * 
     
    599598        /** 
    600599         * If $(B manual reset) is enabled, sleep till the event becomes 
    601          * signaled. The event remains signaled after $(D_CODE wait()) 
    602          * completes. If in $(B auto reset) mode, sleep till the event becomes 
    603          * signaled. In this case the event will be reset after 
    604          * $(D_CODE wait()) completes. 
     600         * signaled. The event remains signaled after wait() completes. If in 
     601         * $(B auto reset) mode, sleep till the event becomes signaled. In 
     602         * this case the event will be reset after wait() completes. 
    605603         */ 
    606604        public void wait() 
     
    615613 
    616614        /** 
    617          * Same as $(D_CODE wait()) above, but this method can be timed. 
     615         * Same as wait() above, but this method can be timed. 
    618616         * $(D_PARAM timeout) is a relative timeout. If the timeout is equal to 
    619          * $(D_CODE Interval.max) then this method behaves like the one 
    620          * above. 
     617         * Interval.max then this method behaves like the one above. 
    621618         * 
    622619         * Returns: true if the event was signaled; false if the timeout 
     
    646643        /** 
    647644         * Check the $(D_PARAM errorCode) argument against possible values 
    648          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    649          * description of the error. 
     645         * of SysError.lastCode() and throw an exception with the description 
     646         * of the error. 
    650647         * 
    651648         * Params: 
  • trunk/tango/util/locks/LockException.d

    r2010 r2016  
    237237    public this(char[] file, uint line) 
    238238    { 
    239         super("The caller does not have access rights to this synchronization object", file, line); 
     239        super("The caller does not have access rights to the synchronization object", file, line); 
     240    } 
     241
     242 
     243/** 
     244 * AlreadyExistsException is thrown when the semaphore could not be created 
     245 * because it already exists. 
     246 */ 
     247public class AlreadyExistsException: LockException 
     248
     249    /** 
     250     * Construct an AlreadyExistsException with the provided text string. 
     251     * 
     252     * Params: 
     253     * file     = name of the source file where the exception was thrown; you 
     254     *            would normally use __FILE__ for this parameter. 
     255     * line     = line number of the source file where the exception was 
     256     *            thrown; you would normally use __LINE__ for this parameter. 
     257     */ 
     258    public this(char[] file, uint line) 
     259    { 
     260        super("The semaphore could not be created because it already exists", file, line); 
    240261    } 
    241262} 
  • trunk/tango/util/locks/Mutex.d

    r2010 r2016  
    2323     * Mutex wrapper that's only valid for threads in the same process. 
    2424     * This implementation is optimized for locking threads that are in the 
    25      * same process. It maps to a $(D_CODE CRITICAL_SECTION) on Windows and to 
    26      * a $(D_CODE pthread_mutex_t) on UNIX. Mutexes on Windows are always 
    27      * recursive, even if the $(D_CODE NonRecursive) mutex type is used. 
     25     * same process. It maps to a CRITICAL_SECTION on Windows and to a 
     26     * pthread_mutex_t on UNIX. Mutexes on Windows are always recursive, even 
     27     * if the NonRecursive mutex type is used. 
    2828     */ 
    2929    public class Mutex 
     
    142142        /** 
    143143         * Check the $(D_PARAM errorCode) argument against possible values 
    144          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    145          * description of the error. 
     144         * of SysError.lastCode() and throw an exception with the description 
     145         * of the error. 
    146146         * 
    147147         * Params: 
     
    304304     * Mutex wrapper that's only valid for threads in the same process. 
    305305     * This implementation is optimized for locking threads that are in the 
    306      * same process. It maps to a $(D_CODE CRITICAL_SECTION) on Windows and to 
    307      * a $(D_CODE pthread_mutex_t) on UNIX. Mutexes on Windows are always 
    308      * recursive, even if the $(D_CODE NonRecursive) mutex type is used. 
     306     * same process. It maps to a CRITICAL_SECTION on Windows and to a 
     307     * pthread_mutex_t on UNIX. Mutexes on Windows are always 
     308     * recursive, even if the NonRecursive mutex type is used. 
    309309     */ 
    310310    private class Mutex 
     
    483483        /** 
    484484         * Check the $(D_PARAM errorCode) argument against possible values 
    485          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    486          * description of the error. 
     485         * of SysError.lastCode() and throw an exception with the description 
     486         * of the error. 
    487487         * 
    488488         * Params: 
  • trunk/tango/util/locks/ReadWriteMutex.d

    r2010 r2016  
    223223        /** 
    224224         * Check the $(D_PARAM errorCode) argument against possible values 
    225          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    226          * description of the error. 
     225         * of SysError.lastCode() and throw an exception with the description 
     226         * of the error. 
    227227         * 
    228228         * Params: 
     
    290290     * Remarks: 
    291291     * Based on the ACE_RW_Mutex class from the 
    292      * $(LINK2 http://www.cs.wustl.edu/~schmidt/ACE.html ACE framework). 
     292     * $(LINK2 http://www.cs.wustl.edu/~schmidt/ACE.html, ACE framework). 
    293293     */ 
    294294    public class ReadWriteMutex 
  • trunk/tango/util/locks/Semaphore.d

    r2010 r2016  
    129129        /** 
    130130         * Check the $(D_PARAM errorCode) argument against possible values 
    131          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    132          * description of the error. 
     131         * of SysError.lastCode() and throw an exception with the description 
     132         * of the error. 
    133133         * 
    134134         * Params: 
     
    163163            switch (errorCode) 
    164164            { 
     165                case EACCES: 
     166                    throw new AccessDeniedException(file, line); 
     167                    // break; 
     168 
     169                case EEXIST: 
     170                    throw new AlreadyExistsException(file, line); 
     171                    // break; 
     172 
    165173                case EBUSY: 
    166174                case EAGAIN: 
     
    264272 
    265273            // By default, both the user and group have access to the semaphore 
    266             _sem = sem_open(_name.ptr, O_CREAT | O_EXCL,  
    267                             S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, count); 
     274            _sem = sem_open(_name.ptr, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, count); 
    268275            if (_sem == SEM_FAILED) 
    269276            { 
     
    403410        /** 
    404411         * Check the $(D_PARAM errorCode) argument against possible values 
    405          * of $(D_CODE SysError.lastCode()) and throw an exception with the 
    406          * description of the error. 
     412         * of SysError.lastCode() and throw an exception with the description 
     413         * of the error. 
    407414         * 
    408415         * Params: