Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Alchemy Viewer
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Package registry
Operate
Terraform modules
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Silent mode is enabled
All outbound communications are blocked.
Learn more
.
Show more breadcrumbs
Alchemy Viewer
Alchemy Viewer
Commits
1709f1ef
"README.md" did not exist on "78910cf3016fc55eaf8214640b348df0f8bcdeda"
Commit
1709f1ef
authored
15 years ago
by
David Parks
Browse files
Options
Downloads
Patches
Plain Diff
Resolved timeout issues in mesh HTTP transfer.
parent
35e25272
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
indra/llcommon/llthread.h
+280
-280
280 additions, 280 deletions
indra/llcommon/llthread.h
with
280 additions
and
280 deletions
indra/llcommon/llthread.h
+
280
−
280
View file @
1709f1ef
/**
/**
* @file llthread.h
* @file llthread.h
* @brief Base classes for thread, mutex and condition handling.
* @brief Base classes for thread, mutex and condition handling.
*
*
* $LicenseInfo:firstyear=2004&license=viewergpl$
* $LicenseInfo:firstyear=2004&license=viewergpl$
*
*
* Copyright (c) 2004-2009, Linden Research, Inc.
* Copyright (c) 2004-2009, Linden Research, Inc.
*
*
* Second Life Viewer Source Code
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
*
* There are special exceptions to the terms and conditions of the GPL as
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
*
* By copying, modifying or distributing this software, you acknowledge
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* and agree to abide by those obligations.
*
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
* $/LicenseInfo$
*/
*/
#ifndef LL_LLTHREAD_H
#ifndef LL_LLTHREAD_H
#define LL_LLTHREAD_H
#define LL_LLTHREAD_H
#include
"llapp.h"
#include
"llapp.h"
#include
"apr_thread_cond.h"
#include
"apr_thread_cond.h"
class
LLThread
;
class
LLThread
;
class
LLMutex
;
class
LLMutex
;
class
LLCondition
;
class
LLCondition
;
#if LL_WINDOWS
#if LL_WINDOWS
#define ll_thread_local __declspec(thread)
#define ll_thread_local __declspec(thread)
#else
#else
#define ll_thread_local __thread
#define ll_thread_local __thread
#endif
#endif
class
LL_COMMON_API
LLThread
class
LL_COMMON_API
LLThread
{
{
private:
private:
static
U32
sIDIter
;
static
U32
sIDIter
;
public:
public:
typedef
enum
e_thread_status
typedef
enum
e_thread_status
{
{
STOPPED
=
0
,
// The thread is not running. Not started, or has exited its run function
STOPPED
=
0
,
// The thread is not running. Not started, or has exited its run function
RUNNING
=
1
,
// The thread is currently running
RUNNING
=
1
,
// The thread is currently running
QUITTING
=
2
// Someone wants this thread to quit
QUITTING
=
2
// Someone wants this thread to quit
}
EThreadStatus
;
}
EThreadStatus
;
LLThread
(
const
std
::
string
&
name
,
apr_pool_t
*
poolp
=
NULL
);
LLThread
(
const
std
::
string
&
name
,
apr_pool_t
*
poolp
=
NULL
);
virtual
~
LLThread
();
// Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
virtual
~
LLThread
();
// Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
virtual
void
shutdown
();
// stops the thread
virtual
void
shutdown
();
// stops the thread
bool
isQuitting
()
const
{
return
(
QUITTING
==
mStatus
);
}
bool
isQuitting
()
const
{
return
(
QUITTING
==
mStatus
);
}
bool
isStopped
()
const
{
return
(
STOPPED
==
mStatus
);
}
bool
isStopped
()
const
{
return
(
STOPPED
==
mStatus
);
}
static
U32
currentID
();
// Return ID of current thread
static
U32
currentID
();
// Return ID of current thread
static
void
yield
();
// Static because it can be called by the main thread, which doesn't have an LLThread data structure.
static
void
yield
();
// Static because it can be called by the main thread, which doesn't have an LLThread data structure.
public
:
public
:
// PAUSE / RESUME functionality. See source code for important usage notes.
// PAUSE / RESUME functionality. See source code for important usage notes.
// Called from MAIN THREAD.
// Called from MAIN THREAD.
void
pause
();
void
pause
();
void
unpause
();
void
unpause
();
bool
isPaused
()
{
return
isStopped
()
||
mPaused
==
TRUE
;
}
bool
isPaused
()
{
return
isStopped
()
||
mPaused
==
TRUE
;
}
// Cause the thread to wake up and check its condition
// Cause the thread to wake up and check its condition
void
wake
();
void
wake
();
// Same as above, but to be used when the condition is already locked.
// Same as above, but to be used when the condition is already locked.
void
wakeLocked
();
void
wakeLocked
();
// Called from run() (CHILD THREAD). Pause the thread if requested until unpaused.
// Called from run() (CHILD THREAD). Pause the thread if requested until unpaused.
void
checkPause
();
void
checkPause
();
// this kicks off the apr thread
// this kicks off the apr thread
void
start
(
void
);
void
start
(
void
);
apr_pool_t
*
getAPRPool
()
{
return
mAPRPoolp
;
}
apr_pool_t
*
getAPRPool
()
{
return
mAPRPoolp
;
}
LLVolatileAPRPool
*
getLocalAPRFilePool
()
{
return
mLocalAPRFilePoolp
;
}
LLVolatileAPRPool
*
getLocalAPRFilePool
()
{
return
mLocalAPRFilePoolp
;
}
U32
getID
()
const
{
return
mID
;
}
U32
getID
()
const
{
return
mID
;
}
private
:
private
:
BOOL
mPaused
;
BOOL
mPaused
;
// static function passed to APR thread creation routine
// static function passed to APR thread creation routine
static
void
*
APR_THREAD_FUNC
staticRun
(
apr_thread_t
*
apr_threadp
,
void
*
datap
);
static
void
*
APR_THREAD_FUNC
staticRun
(
apr_thread_t
*
apr_threadp
,
void
*
datap
);
protected
:
protected
:
std
::
string
mName
;
std
::
string
mName
;
LLCondition
*
mRunCondition
;
LLCondition
*
mRunCondition
;
apr_thread_t
*
mAPRThreadp
;
apr_thread_t
*
mAPRThreadp
;
apr_pool_t
*
mAPRPoolp
;
apr_pool_t
*
mAPRPoolp
;
BOOL
mIsLocalPool
;
BOOL
mIsLocalPool
;
EThreadStatus
mStatus
;
EThreadStatus
mStatus
;
U32
mID
;
U32
mID
;
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
// otherwise it will cause severe memory leaking!!! --bao
// otherwise it will cause severe memory leaking!!! --bao
LLVolatileAPRPool
*
mLocalAPRFilePoolp
;
LLVolatileAPRPool
*
mLocalAPRFilePoolp
;
void
setQuitting
();
void
setQuitting
();
// virtual function overridden by subclass -- this will be called when the thread runs
// virtual function overridden by subclass -- this will be called when the thread runs
virtual
void
run
(
void
)
=
0
;
virtual
void
run
(
void
)
=
0
;
// virtual predicate function -- returns true if the thread should wake up, false if it should sleep.
// virtual predicate function -- returns true if the thread should wake up, false if it should sleep.
virtual
bool
runCondition
(
void
);
virtual
bool
runCondition
(
void
);
// Lock/Unlock Run Condition -- use around modification of any variable used in runCondition()
// Lock/Unlock Run Condition -- use around modification of any variable used in runCondition()
inline
void
lockData
();
inline
void
lockData
();
inline
void
unlockData
();
inline
void
unlockData
();
// This is the predicate that decides whether the thread should sleep.
// This is the predicate that decides whether the thread should sleep.
// It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access
// It should only be called with mRunCondition locked, since the virtual runCondition() function may need to access
// data structures that are thread-unsafe.
// data structures that are thread-unsafe.
bool
shouldSleep
(
void
)
{
return
(
mStatus
==
RUNNING
)
&&
(
isPaused
()
||
(
!
runCondition
()));
}
bool
shouldSleep
(
void
)
{
return
(
mStatus
==
RUNNING
)
&&
(
isPaused
()
||
(
!
runCondition
()));
}
// To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following:
// To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following:
// mRunCondition->lock();
// mRunCondition->lock();
// if(!shouldSleep())
// if(!shouldSleep())
// mRunCondition->signal();
// mRunCondition->signal();
// mRunCondition->unlock();
// mRunCondition->unlock();
};
};
//============================================================================
//============================================================================
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
class
LL_COMMON_API
LLMutex
class
LL_COMMON_API
LLMutex
{
{
public:
public:
typedef
enum
typedef
enum
{
{
NO_THREAD
=
0xFFFFFFFF
NO_THREAD
=
0xFFFFFFFF
}
e_locking_thread
;
}
e_locking_thread
;
LLMutex
(
apr_pool_t
*
apr_poolp
);
// NULL pool constructs a new pool for the mutex
LLMutex
(
apr_pool_t
*
apr_poolp
);
// NULL pool constructs a new pool for the mutex
~
LLMutex
();
~
LLMutex
();
void
lock
();
// blocks
void
lock
();
// blocks
void
unlock
();
void
unlock
();
bool
isLocked
();
// non-blocking, but does do a lock/unlock so not free
bool
isLocked
();
// non-blocking, but does do a lock/unlock so not free
U32
lockingThread
()
const
;
//get ID of locking thread
U32
lockingThread
()
const
;
//get ID of locking thread
protected
:
protected
:
apr_thread_mutex_t
*
mAPRMutexp
;
apr_thread_mutex_t
*
mAPRMutexp
;
mutable
U32
mCount
;
mutable
U32
mCount
;
mutable
U32
mLockingThread
;
mutable
U32
mLockingThread
;
apr_pool_t
*
mAPRPoolp
;
apr_pool_t
*
mAPRPoolp
;
BOOL
mIsLocalPool
;
BOOL
mIsLocalPool
;
S32
mLockCount
;
S32
mLockCount
;
#if MUTEX_DEBUG
#if MUTEX_DEBUG
std
::
map
<
U32
,
BOOL
>
mIsLocked
;
std
::
map
<
U32
,
BOOL
>
mIsLocked
;
#endif
#endif
};
};
// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
// Actually a condition/mutex pair (since each condition needs to be associated with a mutex).
class
LL_COMMON_API
LLCondition
:
public
LLMutex
class
LL_COMMON_API
LLCondition
:
public
LLMutex
{
{
public:
public:
LLCondition
(
apr_pool_t
*
apr_poolp
);
// Defaults to global pool, could use the thread pool as well.
LLCondition
(
apr_pool_t
*
apr_poolp
);
// Defaults to global pool, could use the thread pool as well.
~
LLCondition
();
~
LLCondition
();
void
wait
();
// blocks
void
wait
();
// blocks
void
signal
();
void
signal
();
void
broadcast
();
void
broadcast
();
protected:
protected:
apr_thread_cond_t
*
mAPRCondp
;
apr_thread_cond_t
*
mAPRCondp
;
};
};
class
LLMutexLock
class
LLMutexLock
{
{
public:
public:
LLMutexLock
(
LLMutex
*
mutex
)
LLMutexLock
(
LLMutex
*
mutex
)
{
{
mMutex
=
mutex
;
mMutex
=
mutex
;
mMutex
->
lock
();
mMutex
->
lock
();
}
}
~
LLMutexLock
()
~
LLMutexLock
()
{
{
mMutex
->
unlock
();
mMutex
->
unlock
();
}
}
private
:
private
:
LLMutex
*
mMutex
;
LLMutex
*
mMutex
;
};
};
//============================================================================
//============================================================================
void
LLThread
::
lockData
()
void
LLThread
::
lockData
()
{
{
mRunCondition
->
lock
();
mRunCondition
->
lock
();
}
}
void
LLThread
::
unlockData
()
void
LLThread
::
unlockData
()
{
{
mRunCondition
->
unlock
();
mRunCondition
->
unlock
();
}
}
//============================================================================
//============================================================================
// see llmemory.h for LLPointer<> definition
// see llmemory.h for LLPointer<> definition
class
LL_COMMON_API
LLThreadSafeRefCount
class
LL_COMMON_API
LLThreadSafeRefCount
{
{
public:
public:
static
void
initThreadSafeRefCount
();
// creates sMutex
static
void
initThreadSafeRefCount
();
// creates sMutex
static
void
cleanupThreadSafeRefCount
();
// destroys sMutex
static
void
cleanupThreadSafeRefCount
();
// destroys sMutex
private:
private:
static
LLMutex
*
sMutex
;
static
LLMutex
*
sMutex
;
private:
private:
LLThreadSafeRefCount
(
const
LLThreadSafeRefCount
&
);
// not implemented
LLThreadSafeRefCount
(
const
LLThreadSafeRefCount
&
);
// not implemented
LLThreadSafeRefCount
&
operator
=
(
const
LLThreadSafeRefCount
&
);
// not implemented
LLThreadSafeRefCount
&
operator
=
(
const
LLThreadSafeRefCount
&
);
// not implemented
protected:
protected:
virtual
~
LLThreadSafeRefCount
();
// use unref()
virtual
~
LLThreadSafeRefCount
();
// use unref()
public:
public:
LLThreadSafeRefCount
();
LLThreadSafeRefCount
();
void
ref
()
void
ref
()
{
{
if
(
sMutex
)
sMutex
->
lock
();
if
(
sMutex
)
sMutex
->
lock
();
mRef
++
;
mRef
++
;
if
(
sMutex
)
sMutex
->
unlock
();
if
(
sMutex
)
sMutex
->
unlock
();
}
}
S32
unref
()
S32
unref
()
{
{
llassert
(
mRef
>=
1
);
llassert
(
mRef
>=
1
);
if
(
sMutex
)
sMutex
->
lock
();
if
(
sMutex
)
sMutex
->
lock
();
S32
res
=
--
mRef
;
S32
res
=
--
mRef
;
if
(
sMutex
)
sMutex
->
unlock
();
if
(
sMutex
)
sMutex
->
unlock
();
if
(
0
==
res
)
if
(
0
==
res
)
{
{
delete
this
;
delete
this
;
return
0
;
return
0
;
}
}
return
res
;
return
res
;
}
}
S32
getNumRefs
()
const
S32
getNumRefs
()
const
{
{
return
mRef
;
return
mRef
;
}
}
private
:
private
:
S32
mRef
;
S32
mRef
;
};
};
//============================================================================
//============================================================================
// Simple responder for self destructing callbacks
// Simple responder for self destructing callbacks
// Pure virtual class
// Pure virtual class
class
LL_COMMON_API
LLResponder
:
public
LLThreadSafeRefCount
class
LL_COMMON_API
LLResponder
:
public
LLThreadSafeRefCount
{
{
protected:
protected:
virtual
~
LLResponder
();
virtual
~
LLResponder
();
public:
public:
virtual
void
completed
(
bool
success
)
=
0
;
virtual
void
completed
(
bool
success
)
=
0
;
};
};
//============================================================================
//============================================================================
#endif // LL_LLTHREAD_H
#endif // LL_LLTHREAD_H
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment