nsprpub/pr/src/cplus/rcthread.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /* RCThread.cpp - C++ wrapper on NSPR */
     8 #include "rcthread.h"
     9 #include "rcinrval.h"
    11 #include <prmem.h>
    12 #include <prlog.h>
    13 #include <stdio.h>
    14 #include <prinit.h>
    16 static RCPrimordialThread *primordial = NULL;
    18 void nas_Root(void *arg)
    19 {
    20     RCThread *him = (RCThread*)arg;
    21     while (RCThread::ex_unstarted == him->execution)
    22         (void)PR_Sleep(PR_INTERVAL_NO_TIMEOUT);  /* wait for Start() */
    23     him->RootFunction();  /* he gets a self reference */
    24     if (PR_UNJOINABLE_THREAD == PR_GetThreadState(him->identity))
    25         delete him;
    26 }  /* nas_Root */
    28 RCThread::~RCThread() { }
    30 RCThread::RCThread(): RCBase() { }
    32 RCThread::RCThread(const RCThread&): RCBase()
    33 {
    34     PR_NOT_REACHED("Cannot call thread copy constructor");
    35 }  /* RCThread::RCThread */
    37 RCThread::RCThread(
    38     RCThread::Scope scope, RCThread::State join, PRUint32 stackSize):
    39     RCBase()
    40 {
    41     execution = ex_unstarted;
    42     identity = PR_CreateThread(
    43         PR_USER_THREAD, nas_Root, this,
    44         PR_GetThreadPriority(PR_GetCurrentThread()),
    45         (PRThreadScope)scope, (PRThreadState)join, stackSize);
    46 }  /* RCThread::RCThread */
    48 void RCThread::operator=(const RCThread&)
    49 {
    50     PR_NOT_REACHED("Cannot call thread assignment operator");
    51 }  /* RCThread::operator= */
    54 PRStatus RCThread::Start()
    55 {
    56     PRStatus rv;
    57     /* This is an unsafe check, but not too critical */
    58     if (RCThread::ex_unstarted == execution)
    59     {
    60         execution = RCThread::ex_started;
    61         rv = PR_Interrupt(identity);
    62         PR_ASSERT(PR_SUCCESS == rv);
    63     }
    64     else
    65     {
    66         rv = PR_FAILURE;
    67         PR_SetError(PR_INVALID_STATE_ERROR, 0);
    68     }
    69     return rv;
    70 }  /* RCThread::Start */
    72 PRStatus RCThread::Join()
    73 {
    74     PRStatus rv;
    75     if (RCThread::ex_unstarted == execution)
    76     {
    77         rv = PR_FAILURE;
    78         PR_SetError(PR_INVALID_STATE_ERROR, 0);
    79     }
    80     else rv = PR_JoinThread(identity);
    81     if (PR_SUCCESS == rv) delete this;
    82     return rv;
    83 }  /* RCThread::Join */
    85 PRStatus RCThread::Interrupt()
    86 {
    87     PRStatus rv;
    88     if (RCThread::ex_unstarted == execution)
    89     {
    90         rv = PR_FAILURE;
    91         PR_SetError(PR_INVALID_STATE_ERROR, 0);
    92     }
    93     else rv = PR_Interrupt(identity);
    94     return rv;
    95 }  /* RCThread::Interrupt */
    97 void RCThread::ClearInterrupt() { PR_ClearInterrupt(); }
    99 void RCThread::SetPriority(RCThread::Priority new_priority)
   100     { PR_SetThreadPriority(identity, (PRThreadPriority)new_priority); }
   102 PRThread *RCThread::Self()
   103     { return PR_GetCurrentThread(); }
   105 RCThread::Scope RCThread::GetScope() const
   106     { return (RCThread::Scope)PR_GetThreadScope(identity); }
   108 RCThread::State RCThread::GetState() const
   109     { return (RCThread::State)PR_GetThreadState(identity); }
   111 RCThread::Priority RCThread::GetPriority() const
   112     { return (RCThread::Priority)PR_GetThreadPriority(identity); }
   114 static void _rc_PDDestructor(RCThreadPrivateData* privateData)
   115 {
   116     PR_ASSERT(NULL != privateData);
   117     privateData->Release();
   118 }
   120 static PRThreadPrivateDTOR _tpd_dtor = (PRThreadPrivateDTOR)_rc_PDDestructor;
   122 PRStatus RCThread::NewPrivateIndex(PRUintn* index)
   123     { return PR_NewThreadPrivateIndex(index, _tpd_dtor); }
   125 PRStatus RCThread::SetPrivateData(PRUintn index)
   126     { return PR_SetThreadPrivate(index, NULL); }
   128 PRStatus RCThread::SetPrivateData(PRUintn index, RCThreadPrivateData* data)
   129 {
   130     return PR_SetThreadPrivate(index, data);
   131 }
   133 RCThreadPrivateData* RCThread::GetPrivateData(PRUintn index)
   134     { return (RCThreadPrivateData*)PR_GetThreadPrivate(index); }
   136 PRStatus RCThread::Sleep(const RCInterval& ticks)
   137     { PRIntervalTime tmo = ticks; return PR_Sleep(tmo); }
   139 RCPrimordialThread *RCThread::WrapPrimordialThread()
   140 {
   141     /*
   142     ** This needs to take more care in insuring that the thread
   143     ** being wrapped is really the primordial thread. This code
   144     ** is assuming that the caller is the primordial thread, and
   145     ** there's nothing to insure that.
   146     */
   147     if (NULL == primordial)
   148     {
   149         /* it doesn't have to be perfect */
   150         RCPrimordialThread *me = new RCPrimordialThread();
   151         PR_ASSERT(NULL != me);
   152         if (NULL == primordial)
   153         {
   154             primordial = me;
   155             me->execution = RCThread::ex_started;
   156             me->identity = PR_GetCurrentThread();
   157         }
   158         else delete me;  /* somebody beat us to it */
   159     }
   160     return primordial;
   161 }  /* RCThread::WrapPrimordialThread */
   163 RCPrimordialThread::RCPrimordialThread(): RCThread() { }
   165 RCPrimordialThread::~RCPrimordialThread() { }
   167 void RCPrimordialThread::RootFunction()
   168 {
   169     PR_NOT_REACHED("Primordial thread calling root function"); 
   170 }  /* RCPrimordialThread::RootFunction */
   172 PRStatus RCPrimordialThread::Cleanup() { return PR_Cleanup(); }
   174 PRStatus RCPrimordialThread::SetVirtualProcessors(PRIntn count)
   175 {
   176     PR_SetConcurrency(count);
   177     return PR_SUCCESS;
   178 }  /* SetVirutalProcessors */
   180 RCThreadPrivateData::RCThreadPrivateData() { }
   182 RCThreadPrivateData::RCThreadPrivateData(
   183     const RCThreadPrivateData& him) { }
   185 RCThreadPrivateData::~RCThreadPrivateData() { }
   187 /* RCThread.c */

mercurial