core/logic/thread/PosixThreads.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Feb 09 22:50:20 2014 -0600 (2014-02-09)
changeset 4241 46fdb8cd9883
parent 4025 542dde661d5c
permissions -rw-r--r--
Use == instead of is operator for checking string equality in AMBuild scripts (bug 6043, r=dvander).
dvander@2726
     1
/**
dvander@4025
     2
 * vim: set ts=4 sw=4 tw=99 noet:
dvander@2726
     3
 * =============================================================================
dvander@2726
     4
 * SourceMod
dvander@2726
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
dvander@2726
     6
 * =============================================================================
dvander@2726
     7
 *
dvander@2726
     8
 * This program is free software; you can redistribute it and/or modify it under
dvander@2726
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
dvander@2726
    10
 * Free Software Foundation.
dvander@2726
    11
 * 
dvander@2726
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
dvander@2726
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@2726
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
dvander@2726
    15
 * details.
dvander@2726
    16
 *
dvander@2726
    17
 * You should have received a copy of the GNU General Public License along with
dvander@2726
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@2726
    19
 *
dvander@2726
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
dvander@2726
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
dvander@2726
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
dvander@2726
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
dvander@2726
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
dvander@2726
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
dvander@2726
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
dvander@2726
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@2726
    28
 *
dvander@2726
    29
 * Version: $Id$
dvander@2726
    30
 */
dvander@2726
    31
dvander@2726
    32
#include <unistd.h>
dvander@2726
    33
#include "PosixThreads.h"
dvander@2726
    34
#include "ThreadWorker.h"
dvander@2726
    35
dvander@2726
    36
IThreadWorker *PosixThreader::MakeWorker(IThreadWorkerCallbacks *hooks, bool threaded)
dvander@2726
    37
{
dvander@2726
    38
	if (threaded)
dvander@2726
    39
	{
dvander@2726
    40
		return new ThreadWorker(hooks, this, DEFAULT_THINK_TIME_MS);
dvander@2726
    41
	} else {
dvander@2726
    42
		return new BaseWorker(hooks);
dvander@2726
    43
	}
dvander@2726
    44
}
dvander@2726
    45
dvander@2726
    46
void PosixThreader::DestroyWorker(IThreadWorker *pWorker)
dvander@2726
    47
{
dvander@2726
    48
	delete pWorker;
dvander@2726
    49
}
dvander@2726
    50
dvander@2726
    51
void PosixThreader::ThreadSleep(unsigned int ms)
dvander@2726
    52
{
dvander@2726
    53
	usleep( ms * 1000 );
dvander@2726
    54
}
dvander@2726
    55
dvander@2726
    56
void PosixThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
dvander@2726
    57
{
dvander@2726
    58
	max = ThreadPrio_Normal;
dvander@2726
    59
	min = ThreadPrio_Normal;
dvander@2726
    60
}
dvander@2726
    61
dvander@2726
    62
IMutex *PosixThreader::MakeMutex()
dvander@2726
    63
{
dvander@4025
    64
	return new CompatMutex();
dvander@2726
    65
}
dvander@2726
    66
dvander@2726
    67
void PosixThreader::MakeThread(IThread *pThread)
dvander@2726
    68
{
dvander@2726
    69
	ThreadParams defparams;
dvander@2726
    70
dvander@2726
    71
	defparams.flags = Thread_AutoRelease;
dvander@2726
    72
	defparams.prio = ThreadPrio_Normal;
dvander@2726
    73
dvander@2726
    74
	MakeThread(pThread, &defparams);
dvander@2726
    75
}
dvander@2726
    76
dvander@2726
    77
IThreadHandle *PosixThreader::MakeThread(IThread *pThread, ThreadFlags flags)
dvander@2726
    78
{
dvander@2726
    79
	ThreadParams defparams;
dvander@2726
    80
dvander@2726
    81
	defparams.flags = flags;
dvander@2726
    82
	defparams.prio = ThreadPrio_Normal;
dvander@2726
    83
dvander@2726
    84
	return MakeThread(pThread, &defparams);
dvander@2726
    85
}
dvander@2726
    86
dvander@4025
    87
void PosixThreader::ThreadHandle::Run()
dvander@2726
    88
{
dvander@4025
    89
	// Wait for an unpause if necessary.
dvander@4025
    90
	{
dvander@4025
    91
		ke::AutoLock lock(&m_runlock);
dvander@4025
    92
		if (m_state == Thread_Paused)
dvander@4025
    93
			m_runlock.Wait();
dvander@4025
    94
	}
dvander@2726
    95
dvander@4025
    96
	m_run->RunThread(this);
dvander@4025
    97
	m_state = Thread_Done;
dvander@4025
    98
	m_run->OnTerminate(this, false);
dvander@2726
    99
dvander@4025
   100
	if (m_params.flags & Thread_AutoRelease)
dvander@4025
   101
		delete this;
dvander@2726
   102
}
dvander@2726
   103
dvander@2726
   104
ThreadParams g_defparams;
dvander@2726
   105
IThreadHandle *PosixThreader::MakeThread(IThread *pThread, const ThreadParams *params)
dvander@2726
   106
{
dvander@2726
   107
	if (params == NULL)
dvander@2726
   108
		params = &g_defparams;
dvander@2726
   109
dvander@4025
   110
	ke::AutoPtr<ThreadHandle> pHandle(new ThreadHandle(this, pThread, params));
dvander@2726
   111
dvander@4025
   112
	pHandle->m_thread = new ke::Thread(pHandle, "SourceMod");
dvander@4025
   113
	if (!pHandle->m_thread->Succeeded())
dvander@2726
   114
		return NULL;
dvander@2726
   115
dvander@4025
   116
	if (!(params->flags & Thread_CreateSuspended))
dvander@4025
   117
		pHandle->Unpause();
dvander@2726
   118
dvander@4025
   119
	return pHandle.take();
dvander@2726
   120
}
dvander@2726
   121
dvander@2726
   122
IEventSignal *PosixThreader::MakeEventSignal()
dvander@2726
   123
{
dvander@4025
   124
	return new CompatCondVar();
dvander@2726
   125
}
dvander@2726
   126
dvander@2726
   127
/******************
dvander@2726
   128
* Thread Handles *
dvander@2726
   129
******************/
dvander@2726
   130
dvander@2726
   131
PosixThreader::ThreadHandle::ThreadHandle(IThreader *parent, IThread *run, const ThreadParams *params) : 
dvander@2726
   132
	m_parent(parent), m_params(*params), m_run(run), m_state(Thread_Paused)
dvander@2726
   133
{
dvander@2726
   134
}
dvander@2726
   135
dvander@2726
   136
PosixThreader::ThreadHandle::~ThreadHandle()
dvander@2726
   137
{
dvander@2726
   138
}
dvander@2726
   139
dvander@2726
   140
bool PosixThreader::ThreadHandle::WaitForThread()
dvander@2726
   141
{
dvander@4025
   142
	if (!m_thread)
dvander@2726
   143
		return false;
dvander@2726
   144
dvander@4025
   145
	m_thread->Join();
dvander@2726
   146
	return true;
dvander@2726
   147
}
dvander@2726
   148
dvander@2726
   149
ThreadState PosixThreader::ThreadHandle::GetState()
dvander@2726
   150
{
dvander@4025
   151
	return m_state;
dvander@2726
   152
}
dvander@2726
   153
dvander@2726
   154
IThreadCreator *PosixThreader::ThreadHandle::Parent()
dvander@2726
   155
{
dvander@2726
   156
	return m_parent;
dvander@2726
   157
}
dvander@2726
   158
dvander@2726
   159
void PosixThreader::ThreadHandle::DestroyThis()
dvander@2726
   160
{
dvander@2726
   161
	if (m_params.flags & Thread_AutoRelease)
dvander@2726
   162
		return;
dvander@2726
   163
dvander@2726
   164
	delete this;
dvander@2726
   165
}
dvander@2726
   166
dvander@2726
   167
void PosixThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
dvander@2726
   168
{
dvander@2726
   169
	if (!ptparams)
dvander@2726
   170
		return;
dvander@2726
   171
dvander@2726
   172
	*ptparams = m_params;
dvander@2726
   173
}
dvander@2726
   174
dvander@2726
   175
ThreadPriority PosixThreader::ThreadHandle::GetPriority()
dvander@2726
   176
{
dvander@2726
   177
	return ThreadPrio_Normal;
dvander@2726
   178
}
dvander@2726
   179
dvander@2726
   180
bool PosixThreader::ThreadHandle::SetPriority(ThreadPriority prio)
dvander@2726
   181
{
dvander@2726
   182
	return (prio == ThreadPrio_Normal);
dvander@2726
   183
}
dvander@2726
   184
dvander@2726
   185
bool PosixThreader::ThreadHandle::Unpause()
dvander@2726
   186
{
dvander@2726
   187
	if (m_state != Thread_Paused)
dvander@2726
   188
		return false;
dvander@2726
   189
dvander@4025
   190
	ke::AutoLock lock(&m_runlock);
dvander@2726
   191
	m_state = Thread_Running;
dvander@4025
   192
	m_runlock.Notify();
dvander@2726
   193
	return true;
dvander@2726
   194
}
dvander@2726
   195