DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (27a812186ff4)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef vm_Monitor_h
#define vm_Monitor_h

#ifdef JS_THREADSAFE
#include "mozilla/DebugOnly.h"
#endif

#include <stddef.h>

#include "jslock.h"

#include "js/Utility.h"

namespace js {

// A base class used for types intended to be used in a parallel
// fashion, such as the workers in the |ThreadPool| class.  Combines a
// lock and a condition variable.  You can acquire the lock or signal
// the condition variable using the |AutoLockMonitor| type.

class Monitor
{
  protected:
    friend class AutoLockMonitor;
    friend class AutoUnlockMonitor;

    PRLock* lock_;
    PRCondVar* condVar_;

  public:
    Monitor()
      : lock_(nullptr),
        condVar_(nullptr)
    { }

    ~Monitor() {
#ifdef JS_THREADSAFE
        if (lock_)
            PR_DestroyLock(lock_);
        if (condVar_)
            PR_DestroyCondVar(condVar_);
#endif
    }

    bool init();
};

class AutoLockMonitor
{
  private:
#ifdef JS_THREADSAFE
    Monitor& monitor;
#endif

  public:
    AutoLockMonitor(Monitor& monitor)
#ifdef JS_THREADSAFE
      : monitor(monitor)
    {
        PR_Lock(monitor.lock_);
    }
#else
    {}
#endif

    ~AutoLockMonitor() {
#ifdef JS_THREADSAFE
        PR_Unlock(monitor.lock_);
#endif
    }

    bool isFor(Monitor& other) const {
#ifdef JS_THREADSAFE
        return monitor.lock_ == other.lock_;
#else
        return true;
#endif
    }

    void wait(PRCondVar* condVar) {
#ifdef JS_THREADSAFE
        mozilla::DebugOnly<PRStatus> status =
          PR_WaitCondVar(condVar, PR_INTERVAL_NO_TIMEOUT);
        MOZ_ASSERT(status == PR_SUCCESS);
#endif
    }

    void wait() {
#ifdef JS_THREADSAFE
        wait(monitor.condVar_);
#endif
    }

    void notify(PRCondVar* condVar) {
#ifdef JS_THREADSAFE
        mozilla::DebugOnly<PRStatus> status = PR_NotifyCondVar(condVar);
        MOZ_ASSERT(status == PR_SUCCESS);
#endif
    }

    void notify() {
#ifdef JS_THREADSAFE
        notify(monitor.condVar_);
#endif
    }

    void notifyAll(PRCondVar* condVar) {
#ifdef JS_THREADSAFE
        mozilla::DebugOnly<PRStatus> status = PR_NotifyAllCondVar(monitor.condVar_);
        MOZ_ASSERT(status == PR_SUCCESS);
#endif
    }

    void notifyAll() {
#ifdef JS_THREADSAFE
        notifyAll(monitor.condVar_);
#endif
    }
};

class AutoUnlockMonitor
{
  private:
#ifdef JS_THREADSAFE
    Monitor& monitor;
#endif

  public:
    AutoUnlockMonitor(Monitor& monitor)
#ifdef JS_THREADSAFE
      : monitor(monitor)
    {
        PR_Unlock(monitor.lock_);
    }
#else
    {}
#endif

    ~AutoUnlockMonitor() {
#ifdef JS_THREADSAFE
        PR_Lock(monitor.lock_);
#endif
    }

    bool isFor(Monitor& other) const {
#ifdef JS_THREADSAFE
        return monitor.lock_ == other.lock_;
#else
        return true;
#endif
    }
};

} // namespace js

#endif /* vm_Monitor_h */