Revert "remove JMutex, and delete jthread from source tree"

This reverts commit 5c594840bb294e62cb317f553ef2ddc0acdaa4ca.

Conflicts:
	src/CMakeLists.txt
This commit is contained in:
darkrose 2014-07-12 21:27:32 +10:00
parent c2900aa9fc
commit f7f60fac02
40 changed files with 1690 additions and 864 deletions

View File

@ -81,6 +81,7 @@ else()
set(CLIENT_PLATFORM_LIBS ${CLIENT_PLATFORM_LIBS} ${XXF86VM_LIBRARY}) set(CLIENT_PLATFORM_LIBS ${CLIENT_PLATFORM_LIBS} ${XXF86VM_LIBRARY})
endif() endif()
find_package(Jthread REQUIRED)
find_package(Sqlite3 REQUIRED) find_package(Sqlite3 REQUIRED)
configure_file( configure_file(
@ -98,7 +99,6 @@ set(common_SRCS
content_craftitem.cpp content_craftitem.cpp
content_toolitem.cpp content_toolitem.cpp
content_mapnode.cpp content_mapnode.cpp
content_mapnode_util.cpp
content_list.cpp content_list.cpp
content_nodebox.cpp content_nodebox.cpp
auth.cpp auth.cpp
@ -124,6 +124,7 @@ set(common_SRCS
mapblock.cpp mapblock.cpp
mapsector.cpp mapsector.cpp
map.cpp map.cpp
mesh.cpp
player.cpp player.cpp
utility.cpp utility.cpp
test.cpp test.cpp
@ -153,7 +154,6 @@ set(minetest_SRCS
content_mapblock.cpp content_mapblock.cpp
content_cao.cpp content_cao.cpp
mapblock_mesh.cpp mapblock_mesh.cpp
mesh.cpp
farmesh.cpp farmesh.cpp
keycode.cpp keycode.cpp
camera.cpp camera.cpp
@ -187,6 +187,7 @@ include_directories(
${CMAKE_BUILD_TYPE} ${CMAKE_BUILD_TYPE}
${PNG_INCLUDE_DIR} ${PNG_INCLUDE_DIR}
${GETTEXT_INCLUDE_DIR} ${GETTEXT_INCLUDE_DIR}
${JTHREAD_INCLUDE_DIR}
${SQLITE3_INCLUDE_DIR} ${SQLITE3_INCLUDE_DIR}
) )
@ -204,6 +205,7 @@ if(BUILD_CLIENT)
${PNG_LIBRARIES} ${PNG_LIBRARIES}
${X11_LIBRARIES} ${X11_LIBRARIES}
${GETTEXT_LIBRARY} ${GETTEXT_LIBRARY}
${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY} ${SQLITE3_LIBRARY}
${PLATFORM_LIBS} ${PLATFORM_LIBS}
${CLIENT_PLATFORM_LIBS} ${CLIENT_PLATFORM_LIBS}
@ -215,6 +217,7 @@ if(BUILD_SERVER)
target_link_libraries( target_link_libraries(
${PROJECT_NAME}-server ${PROJECT_NAME}-server
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY} ${SQLITE3_LIBRARY}
${PLATFORM_LIBS} ${PLATFORM_LIBS}
) )
@ -362,6 +365,11 @@ endif(USE_GETTEXT)
# Subdirectories # Subdirectories
if (JTHREAD_FOUND)
else (JTHREAD_FOUND)
add_subdirectory(jthread)
endif (JTHREAD_FOUND)
if (SQLITE3_FOUND) if (SQLITE3_FOUND)
else (SQLITE3_FOUND) else (SQLITE3_FOUND)
add_subdirectory(sqlite) add_subdirectory(sqlite)

View File

@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "auth.h" #include "auth.h"
#include <fstream> #include <fstream>
#include <jmutexautolock.h>
//#include "main.h" // for g_settings //#include "main.h" // for g_settings
#include <sstream> #include <sstream>
#include "strfnd.h" #include "strfnd.h"
@ -83,7 +84,7 @@ AuthManager::AuthManager(const std::string &authfilepath):
m_authfilepath(authfilepath), m_authfilepath(authfilepath),
m_modified(false) m_modified(false)
{ {
m_mutex.init(); m_mutex.Init();
try{ try{
load(); load();
@ -102,7 +103,7 @@ AuthManager::~AuthManager()
void AuthManager::load() void AuthManager::load()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
dstream<<"AuthManager: loading from "<<m_authfilepath<<std::endl; dstream<<"AuthManager: loading from "<<m_authfilepath<<std::endl;
std::ifstream is(m_authfilepath.c_str(), std::ios::binary); std::ifstream is(m_authfilepath.c_str(), std::ios::binary);
@ -148,7 +149,7 @@ void AuthManager::load()
void AuthManager::save() void AuthManager::save()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
dstream<<"AuthManager: saving to "<<m_authfilepath<<std::endl; dstream<<"AuthManager: saving to "<<m_authfilepath<<std::endl;
std::ofstream os(m_authfilepath.c_str(), std::ios::binary); std::ofstream os(m_authfilepath.c_str(), std::ios::binary);
@ -174,7 +175,7 @@ void AuthManager::save()
bool AuthManager::exists(const std::string &username) bool AuthManager::exists(const std::string &username)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n; core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username); n = m_authdata.find(username);
@ -185,7 +186,7 @@ bool AuthManager::exists(const std::string &username)
void AuthManager::set(const std::string &username, AuthData ad) void AuthManager::set(const std::string &username, AuthData ad)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_authdata[username] = ad; m_authdata[username] = ad;
@ -194,7 +195,7 @@ void AuthManager::set(const std::string &username, AuthData ad)
void AuthManager::add(const std::string &username) void AuthManager::add(const std::string &username)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_authdata[username] = AuthData(); m_authdata[username] = AuthData();
@ -203,7 +204,7 @@ void AuthManager::add(const std::string &username)
std::string AuthManager::getPassword(const std::string &username) std::string AuthManager::getPassword(const std::string &username)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n; core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username); n = m_authdata.find(username);
@ -216,7 +217,7 @@ std::string AuthManager::getPassword(const std::string &username)
void AuthManager::setPassword(const std::string &username, void AuthManager::setPassword(const std::string &username,
const std::string &password) const std::string &password)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n; core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username); n = m_authdata.find(username);
@ -232,7 +233,7 @@ void AuthManager::setPassword(const std::string &username,
u64 AuthManager::getPrivs(const std::string &username) u64 AuthManager::getPrivs(const std::string &username)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n; core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username); n = m_authdata.find(username);
@ -244,7 +245,7 @@ u64 AuthManager::getPrivs(const std::string &username)
void AuthManager::setPrivs(const std::string &username, u64 privs) void AuthManager::setPrivs(const std::string &username, u64 privs)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::map<std::string, AuthData>::Node *n; core::map<std::string, AuthData>::Node *n;
n = m_authdata.find(username); n = m_authdata.find(username);
@ -260,7 +261,7 @@ void AuthManager::setPrivs(const std::string &username, u64 privs)
bool AuthManager::isModified() bool AuthManager::isModified()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return m_modified; return m_modified;
} }

View File

@ -21,10 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define AUTH_HEADER #define AUTH_HEADER
#include <string> #include <string>
#include <jthread.h>
#include <jmutex.h>
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "exceptions.h" #include "exceptions.h"
#include "porting.h"
#include "threads.h" using namespace jthread;
// Player privileges. These form a bitmask stored in the privs field // Player privileges. These form a bitmask stored in the privs field
// of the player, and define things they're allowed to do. See also // of the player, and define things they're allowed to do. See also
@ -92,7 +94,7 @@ public:
void setPrivs(const std::string &username, u64 privs); void setPrivs(const std::string &username, u64 privs);
bool isModified(); bool isModified();
private: private:
SimpleMutex m_mutex; JMutex m_mutex;
std::string m_authfilepath; std::string m_authfilepath;
core::map<std::string, AuthData> m_authdata; core::map<std::string, AuthData> m_authdata;
bool m_modified; bool m_modified;

View File

@ -19,17 +19,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "ban.h" #include "ban.h"
#include <fstream> #include <fstream>
#include <jmutexautolock.h>
#include <sstream> #include <sstream>
#include <set> #include <set>
#include "strfnd.h" #include "strfnd.h"
#include "debug.h" #include "debug.h"
#include "threads.h"
BanManager::BanManager(const std::string &banfilepath): BanManager::BanManager(const std::string &banfilepath):
m_banfilepath(banfilepath), m_banfilepath(banfilepath),
m_modified(false) m_modified(false)
{ {
m_mutex.init(); m_mutex.Init();
try{ try{
load(); load();
} }
@ -47,7 +47,7 @@ BanManager::~BanManager()
void BanManager::load() void BanManager::load()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
dstream<<"BanManager: loading from "<<m_banfilepath<<std::endl; dstream<<"BanManager: loading from "<<m_banfilepath<<std::endl;
std::ifstream is(m_banfilepath.c_str(), std::ios::binary); std::ifstream is(m_banfilepath.c_str(), std::ios::binary);
if(is.good() == false) if(is.good() == false)
@ -74,7 +74,7 @@ void BanManager::load()
void BanManager::save() void BanManager::save()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
dstream<<"BanManager: saving to "<<m_banfilepath<<std::endl; dstream<<"BanManager: saving to "<<m_banfilepath<<std::endl;
std::ofstream os(m_banfilepath.c_str(), std::ios::binary); std::ofstream os(m_banfilepath.c_str(), std::ios::binary);
@ -95,13 +95,13 @@ void BanManager::save()
bool BanManager::isIpBanned(const std::string &ip) bool BanManager::isIpBanned(const std::string &ip)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return m_ips.find(ip) != m_ips.end(); return m_ips.find(ip) != m_ips.end();
} }
std::string BanManager::getBanDescription(const std::string &ip_or_name) std::string BanManager::getBanDescription(const std::string &ip_or_name)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
std::string s = ""; std::string s = "";
for(std::map<std::string, std::string>::iterator for(std::map<std::string, std::string>::iterator
i = m_ips.begin(); i = m_ips.begin();
@ -117,7 +117,7 @@ std::string BanManager::getBanDescription(const std::string &ip_or_name)
std::string BanManager::getBanName(const std::string &ip) std::string BanManager::getBanName(const std::string &ip)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
std::map<std::string, std::string>::iterator i = m_ips.find(ip); std::map<std::string, std::string>::iterator i = m_ips.find(ip);
if(i == m_ips.end()) if(i == m_ips.end())
return ""; return "";
@ -126,14 +126,14 @@ std::string BanManager::getBanName(const std::string &ip)
void BanManager::add(const std::string &ip, const std::string &name) void BanManager::add(const std::string &ip, const std::string &name)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_ips[ip] = name; m_ips[ip] = name;
m_modified = true; m_modified = true;
} }
void BanManager::remove(const std::string &ip_or_name) void BanManager::remove(const std::string &ip_or_name)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
//m_ips.erase(m_ips.find(ip)); //m_ips.erase(m_ips.find(ip));
// Find out all ip-name pairs that match the ip or name // Find out all ip-name pairs that match the ip or name
std::set<std::string> ips_to_delete; std::set<std::string> ips_to_delete;
@ -157,7 +157,7 @@ void BanManager::remove(const std::string &ip_or_name)
bool BanManager::isModified() bool BanManager::isModified()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return m_modified; return m_modified;
} }

View File

@ -22,10 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <map> #include <map>
#include <string> #include <string>
#include <jthread.h>
#include <jmutex.h>
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "exceptions.h" #include "exceptions.h"
#include "porting.h"
#include "threads.h" using namespace jthread;
class BanManager class BanManager
{ {
@ -42,7 +44,7 @@ public:
void remove(const std::string &ip_or_name); void remove(const std::string &ip_or_name);
bool isModified(); bool isModified();
private: private:
SimpleMutex m_mutex; JMutex m_mutex;
std::string m_banfilepath; std::string m_banfilepath;
std::map<std::string, std::string> m_ips; std::map<std::string, std::string> m_ips;
bool m_modified; bool m_modified;

View File

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h" #include "utility.h"
#include <iostream> #include <iostream>
#include "clientserver.h" #include "clientserver.h"
#include "jmutexautolock.h"
#include "main.h" #include "main.h"
#include <sstream> #include <sstream>
#include "porting.h" #include "porting.h"
@ -31,7 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "profiler.h" #include "profiler.h"
#include "log.h" #include "log.h"
#include "http.h" #include "http.h"
#include "threads.h"
/* /*
QueuedMeshUpdate QueuedMeshUpdate
@ -56,12 +56,12 @@ QueuedMeshUpdate::~QueuedMeshUpdate()
MeshUpdateQueue::MeshUpdateQueue() MeshUpdateQueue::MeshUpdateQueue()
{ {
m_mutex.init(); m_mutex.Init();
} }
MeshUpdateQueue::~MeshUpdateQueue() MeshUpdateQueue::~MeshUpdateQueue()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::list<QueuedMeshUpdate*>::Iterator i; core::list<QueuedMeshUpdate*>::Iterator i;
for(i=m_queue.begin(); i!=m_queue.end(); i++) for(i=m_queue.begin(); i!=m_queue.end(); i++)
@ -80,7 +80,7 @@ void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_se
assert(data); assert(data);
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
/* /*
Find if block is already in queue. Find if block is already in queue.
@ -115,7 +115,7 @@ void MeshUpdateQueue::addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_se
// Returns NULL if queue is empty // Returns NULL if queue is empty
QueuedMeshUpdate * MeshUpdateQueue::pop() QueuedMeshUpdate * MeshUpdateQueue::pop()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::list<QueuedMeshUpdate*>::Iterator i = m_queue.begin(); core::list<QueuedMeshUpdate*>::Iterator i = m_queue.begin();
if(i == m_queue.end()) if(i == m_queue.end())
@ -217,7 +217,7 @@ Client::Client(
Add local player Add local player
*/ */
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
Player *player = new LocalPlayer(); Player *player = new LocalPlayer();
@ -233,7 +233,7 @@ Client::Client(
Client::~Client() Client::~Client()
{ {
{ {
//SimpleMutexAutoLock conlock(m_con_mutex); //bulk comment-out //JMutexAutoLock conlock(m_con_mutex); //bulk comment-out
m_con.Disconnect(); m_con.Disconnect();
} }
if (g_settings->getBool("enable_http")) if (g_settings->getBool("enable_http"))
@ -245,7 +245,7 @@ Client::~Client()
void Client::connect(Address address) void Client::connect(Address address)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
m_con.SetTimeoutMs(0); m_con.SetTimeoutMs(0);
m_con.Connect(address); m_con.Connect(address);
if (g_settings->getBool("enable_http")) if (g_settings->getBool("enable_http"))
@ -254,7 +254,7 @@ void Client::connect(Address address)
bool Client::connectedAndInitialized() bool Client::connectedAndInitialized()
{ {
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
if(m_con.Connected() == false) if(m_con.Connected() == false)
return false; return false;
@ -289,7 +289,7 @@ void Client::step(float dtime)
{ {
//TimeTaker timer("m_con_mutex + m_con.RunTimeouts()", m_device); //TimeTaker timer("m_con_mutex + m_con.RunTimeouts()", m_device);
// 0ms // 0ms
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
m_con.RunTimeouts(dtime); m_con.RunTimeouts(dtime);
} }
@ -329,7 +329,7 @@ void Client::step(float dtime)
//counter = 180.0; //counter = 180.0;
counter = 60.0; counter = 60.0;
//SimpleMutexAutoLock lock(m_env_mutex); //bulk comment-out //JMutexAutoLock lock(m_env_mutex); //bulk comment-out
core::list<v3s16> deleted_blocks; core::list<v3s16> deleted_blocks;
@ -358,7 +358,7 @@ void Client::step(float dtime)
*/ */
// Env is locked so con can be locked. // Env is locked so con can be locked.
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
core::list<v3s16>::Iterator i = deleted_blocks.begin(); core::list<v3s16>::Iterator i = deleted_blocks.begin();
core::list<v3s16> sendlist; core::list<v3s16> sendlist;
@ -411,7 +411,7 @@ void Client::step(float dtime)
{ {
counter = 2.0; counter = 2.0;
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
Player *myplayer = m_env.getLocalPlayer(); Player *myplayer = m_env.getLocalPlayer();
assert(myplayer != NULL); assert(myplayer != NULL);
@ -516,7 +516,7 @@ void Client::step(float dtime)
*/ */
{ {
// 0ms // 0ms
//SimpleMutexAutoLock lock(m_env_mutex); //bulk comment-out //JMutexAutoLock lock(m_env_mutex); //bulk comment-out
// Control local player (0ms) // Control local player (0ms)
LocalPlayer *player = m_env.getLocalPlayer(); LocalPlayer *player = m_env.getLocalPlayer();
@ -563,7 +563,7 @@ void Client::step(float dtime)
if(counter >= 10) if(counter >= 10)
{ {
counter = 0.0; counter = 0.0;
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
// connectedAndInitialized() is true, peer exists. // connectedAndInitialized() is true, peer exists.
float avg_rtt = m_con.GetPeerAvgRTT(PEER_ID_SERVER); float avg_rtt = m_con.GetPeerAvgRTT(PEER_ID_SERVER);
infostream<<"Client: avg_rtt="<<avg_rtt<<std::endl; infostream<<"Client: avg_rtt="<<avg_rtt<<std::endl;
@ -587,7 +587,7 @@ void Client::step(float dtime)
Replace updated meshes Replace updated meshes
*/ */
{ {
//SimpleMutexAutoLock lock(m_env_mutex); //bulk comment-out //JMutexAutoLock lock(m_env_mutex); //bulk comment-out
//TimeTaker timer("** Processing mesh update result queue"); //TimeTaker timer("** Processing mesh update result queue");
// 0ms // 0ms
@ -672,7 +672,7 @@ void Client::Receive()
u32 datasize; u32 datasize;
{ {
//TimeTaker t1("con mutex and receive", m_device); //TimeTaker t1("con mutex and receive", m_device);
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
datasize = m_con.Receive(sender_peer_id, data); datasize = m_con.Receive(sender_peer_id, data);
} }
//TimeTaker t1("ProcessData", m_device); //TimeTaker t1("ProcessData", m_device);
@ -741,7 +741,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
v3f playerpos_f = intToFloat(playerpos_s16, BS) - v3f(0, BS/2, 0); v3f playerpos_f = intToFloat(playerpos_s16, BS) - v3f(0, BS/2, 0);
{ //envlock { //envlock
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
// Set player position // Set player position
Player *player = m_env.getLocalPlayer(); Player *player = m_env.getLocalPlayer();
@ -927,7 +927,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
<<std::endl; <<std::endl;
/*u16 our_peer_id; /*u16 our_peer_id;
{ {
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
our_peer_id = m_con.GetPeerID(); our_peer_id = m_con.GetPeerID();
} }
// Cancel if we don't have a peer id // Cancel if we don't have a peer id
@ -939,7 +939,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
}*/ }*/
{ //envlock { //envlock
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
u32 player_size = 2+12+12+4+4; u32 player_size = 2+12+12+4+4;
@ -993,7 +993,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
{ {
u16 our_peer_id; u16 our_peer_id;
{ {
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
our_peer_id = m_con.GetPeerID(); our_peer_id = m_con.GetPeerID();
} }
// Cancel if we don't have a peer id // Cancel if we don't have a peer id
@ -1007,7 +1007,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
//infostream<<"Client: Server reports players:"<<std::endl; //infostream<<"Client: Server reports players:"<<std::endl;
{ //envlock { //envlock
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
u32 item_size = 2+PLAYERNAME_SIZE; u32 item_size = 2+PLAYERNAME_SIZE;
u32 player_count = (datasize-2) / item_size; u32 player_count = (datasize-2) / item_size;
@ -1130,7 +1130,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
//infostream<<"Client received TOCLIENT_SECTORMETA"<<std::endl; //infostream<<"Client received TOCLIENT_SECTORMETA"<<std::endl;
{ //envlock { //envlock
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
std::string datastring((char*)&data[2], datasize-2); std::string datastring((char*)&data[2], datasize-2);
std::istringstream is(datastring, std::ios_base::binary); std::istringstream is(datastring, std::ios_base::binary);
@ -1165,7 +1165,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
{ //envlock { //envlock
//TimeTaker t2("mutex locking", m_device); //TimeTaker t2("mutex locking", m_device);
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
//t2.stop(); //t2.stop();
//TimeTaker t3("istringstream init", m_device); //TimeTaker t3("istringstream init", m_device);
@ -1345,7 +1345,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
u16 id = readU16((u8*)buf); u16 id = readU16((u8*)buf);
// Remove it // Remove it
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
m_env.removeActiveObject(id); m_env.removeActiveObject(id);
} }
} }
@ -1362,7 +1362,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
std::string data = deSerializeLongString(is); std::string data = deSerializeLongString(is);
// Add it // Add it
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
m_env.addActiveObject(id, type, data); m_env.addActiveObject(id, type, data);
} }
} }
@ -1405,7 +1405,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
} }
// Pass on to the environment // Pass on to the environment
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
m_env.processActiveObjectMessage(id, message); m_env.processActiveObjectMessage(id, message);
} }
} }
@ -1540,7 +1540,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
void Client::Send(u16 channelnum, SharedBuffer<u8> data, bool reliable) void Client::Send(u16 channelnum, SharedBuffer<u8> data, bool reliable)
{ {
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
m_con.Send(PEER_ID_SERVER, channelnum, data, reliable); m_con.Send(PEER_ID_SERVER, channelnum, data, reliable);
} }
@ -1794,7 +1794,7 @@ void Client::sendWantCookie()
void Client::sendPlayerPos() void Client::sendPlayerPos()
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
Player *myplayer = m_env.getLocalPlayer(); Player *myplayer = m_env.getLocalPlayer();
if(myplayer == NULL) if(myplayer == NULL)
@ -1802,7 +1802,7 @@ void Client::sendPlayerPos()
u16 our_peer_id; u16 our_peer_id;
{ {
//SimpleMutexAutoLock lock(m_con_mutex); //bulk comment-out //JMutexAutoLock lock(m_con_mutex); //bulk comment-out
our_peer_id = m_con.GetPeerID(); our_peer_id = m_con.GetPeerID();
} }
@ -1863,7 +1863,7 @@ void Client::sendPlayerItem(u16 item)
void Client::removeNode(v3s16 p) void Client::removeNode(v3s16 p)
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
core::map<v3s16, MapBlock*> modified_blocks; core::map<v3s16, MapBlock*> modified_blocks;
@ -1888,7 +1888,7 @@ void Client::removeNode(v3s16 p)
void Client::addNode(v3s16 p, MapNode n) void Client::addNode(v3s16 p, MapNode n)
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
TimeTaker timer1("Client::addNode()"); TimeTaker timer1("Client::addNode()");
@ -1927,7 +1927,7 @@ void Client::renderPostFx()
MapNode Client::getNode(v3s16 p) MapNode Client::getNode(v3s16 p)
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
return m_env.getMap().getNode(p); return m_env.getMap().getNode(p);
} }
@ -1943,7 +1943,7 @@ LocalPlayer* Client::getLocalPlayer()
void Client::setPlayerControl(PlayerControl &control) void Client::setPlayerControl(PlayerControl &control)
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
LocalPlayer *player = m_env.getLocalPlayer(); LocalPlayer *player = m_env.getLocalPlayer();
assert(player != NULL); assert(player != NULL);
player->control = control; player->control = control;
@ -1964,7 +1964,7 @@ void Client::selectPlayerItem(u16 item)
bool Client::getLocalInventoryUpdated() bool Client::getLocalInventoryUpdated()
{ {
// m_inventory_updated is behind envlock // m_inventory_updated is behind envlock
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
bool updated = m_inventory_updated; bool updated = m_inventory_updated;
m_inventory_updated = false; m_inventory_updated = false;
return updated; return updated;
@ -1973,7 +1973,7 @@ bool Client::getLocalInventoryUpdated()
// Copies the inventory of the local player to parameter // Copies the inventory of the local player to parameter
void Client::getLocalInventory(Inventory &dst) void Client::getLocalInventory(Inventory &dst)
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
Player *player = m_env.getLocalPlayer(); Player *player = m_env.getLocalPlayer();
assert(player != NULL); assert(player != NULL);
dst = player->inventory; dst = player->inventory;
@ -2096,8 +2096,8 @@ ClientActiveObject * Client::getSelectedActiveObject(
void Client::printDebugInfo(std::ostream &os) void Client::printDebugInfo(std::ostream &os)
{ {
//SimpleMutexAutoLock lock1(m_fetchblock_mutex); //JMutexAutoLock lock1(m_fetchblock_mutex);
/*SimpleMutexAutoLock lock2(m_incoming_queue_mutex); /*JMutexAutoLock lock2(m_incoming_queue_mutex);
os<<"m_incoming_queue.getSize()="<<m_incoming_queue.getSize() os<<"m_incoming_queue.getSize()="<<m_incoming_queue.getSize()
//<<", m_fetchblock_history.size()="<<m_fetchblock_history.size() //<<", m_fetchblock_history.size()="<<m_fetchblock_history.size()
@ -2107,7 +2107,7 @@ void Client::printDebugInfo(std::ostream &os)
u32 Client::getDayNightRatio() u32 Client::getDayNightRatio()
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
return m_env.getDayNightRatio(); return m_env.getDayNightRatio();
} }
@ -2120,7 +2120,7 @@ u16 Client::getHP()
void Client::setTempMod(v3s16 p, NodeMod mod) void Client::setTempMod(v3s16 p, NodeMod mod)
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
core::map<v3s16, MapBlock*> affected_blocks; core::map<v3s16, MapBlock*> affected_blocks;
@ -2137,7 +2137,7 @@ void Client::setTempMod(v3s16 p, NodeMod mod)
void Client::clearTempMod(v3s16 p) void Client::clearTempMod(v3s16 p)
{ {
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
core::map<v3s16, MapBlock*> affected_blocks; core::map<v3s16, MapBlock*> affected_blocks;

View File

@ -25,11 +25,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "connection.h" #include "connection.h"
#include "environment.h" #include "environment.h"
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "jmutex.h"
#include <ostream> #include <ostream>
#include "clientobject.h" #include "clientobject.h"
#include "particles.h" #include "particles.h"
#include "utility.h" // For IntervalLimiter #include "utility.h" // For IntervalLimiter
#include "threads.h"
struct MeshMakeData; struct MeshMakeData;
@ -72,13 +72,13 @@ public:
u32 size() u32 size()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return m_queue.size(); return m_queue.size();
} }
private: private:
core::list<QueuedMeshUpdate*> m_queue; core::list<QueuedMeshUpdate*> m_queue;
SimpleMutex m_mutex; JMutex m_mutex;
}; };
class MapBlockMesh; class MapBlockMesh;
@ -287,7 +287,7 @@ public:
return; return;
} }
//SimpleMutexAutoLock envlock(m_env_mutex); //bulk comment-out //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
LocalPlayer *player = m_env.getLocalPlayer(); LocalPlayer *player = m_env.getLocalPlayer();
assert(player != NULL); assert(player != NULL);
std::wstring name = narrow_to_wide(player->getName()); std::wstring name = narrow_to_wide(player->getName());

View File

@ -543,7 +543,6 @@ Connection::~Connection()
void * Connection::Thread() void * Connection::Thread()
{ {
printf("Connection::Thread()\n");
log_register_thread("Connection"); log_register_thread("Connection");
dout_con<<"Connection thread started"<<std::endl; dout_con<<"Connection thread started"<<std::endl;
@ -566,7 +565,6 @@ printf("Connection::Thread()\n");
runTimeouts(dtime); runTimeouts(dtime);
while(m_command_queue.size() != 0){ while(m_command_queue.size() != 0){
printf("m_command_queue.size() = %u\n",m_command_queue.size());
ConnectionCommand c = m_command_queue.pop_front(); ConnectionCommand c = m_command_queue.pop_front();
processCommand(c); processCommand(c);
} }
@ -577,7 +575,6 @@ printf("m_command_queue.size() = %u\n",m_command_queue.size());
END_DEBUG_EXCEPTION_HANDLER(derr_con); END_DEBUG_EXCEPTION_HANDLER(derr_con);
} }
printf("Connection::Thread() exit\n");
return NULL; return NULL;
} }
@ -1566,7 +1563,7 @@ void Connection::Connect(Address address)
bool Connection::Connected() bool Connection::Connected()
{ {
SimpleMutexAutoLock peerlock(m_peers_mutex); JMutexAutoLock peerlock(m_peers_mutex);
if(m_peers.size() != 1) if(m_peers.size() != 1)
return false; return false;
@ -1643,13 +1640,13 @@ void Connection::RunTimeouts(float dtime)
Address Connection::GetPeerAddress(u16 peer_id) Address Connection::GetPeerAddress(u16 peer_id)
{ {
SimpleMutexAutoLock peerlock(m_peers_mutex); JMutexAutoLock peerlock(m_peers_mutex);
return getPeer(peer_id)->address; return getPeer(peer_id)->address;
} }
float Connection::GetPeerAvgRTT(u16 peer_id) float Connection::GetPeerAvgRTT(u16 peer_id)
{ {
SimpleMutexAutoLock peerlock(m_peers_mutex); JMutexAutoLock peerlock(m_peers_mutex);
return getPeer(peer_id)->avg_rtt; return getPeer(peer_id)->avg_rtt;
} }

View File

@ -609,7 +609,7 @@ private:
u16 m_peer_id; u16 m_peer_id;
core::map<u16, Peer*> m_peers; core::map<u16, Peer*> m_peers;
SimpleMutex m_peers_mutex; JMutex m_peers_mutex;
// Backwards compatibility // Backwards compatibility
PeerHandler *m_bc_peerhandler; PeerHandler *m_bc_peerhandler;

View File

@ -115,16 +115,16 @@ void DebugStack::print(FILE *file, bool everything)
core::map<threadid_t, DebugStack*> g_debug_stacks; core::map<threadid_t, DebugStack*> g_debug_stacks;
SimpleMutex g_debug_stacks_mutex; JMutex g_debug_stacks_mutex;
void debug_stacks_init() void debug_stacks_init()
{ {
g_debug_stacks_mutex.init(); g_debug_stacks_mutex.Init();
} }
void debug_stacks_print() void debug_stacks_print()
{ {
SimpleMutexAutoLock lock(g_debug_stacks_mutex); JMutexAutoLock lock(g_debug_stacks_mutex);
DEBUGPRINT("Debug stacks:\n"); DEBUGPRINT("Debug stacks:\n");
@ -146,7 +146,7 @@ DebugStacker::DebugStacker(const char *text)
{ {
threadid_t threadid = get_current_thread_id(); threadid_t threadid = get_current_thread_id();
SimpleMutexAutoLock lock(g_debug_stacks_mutex); JMutexAutoLock lock(g_debug_stacks_mutex);
core::map<threadid_t, DebugStack*>::Node *n; core::map<threadid_t, DebugStack*>::Node *n;
n = g_debug_stacks.find(threadid); n = g_debug_stacks.find(threadid);
@ -180,7 +180,7 @@ DebugStacker::DebugStacker(const char *text)
DebugStacker::~DebugStacker() DebugStacker::~DebugStacker()
{ {
SimpleMutexAutoLock lock(g_debug_stacks_mutex); JMutexAutoLock lock(g_debug_stacks_mutex);
if(m_overflowed == true) if(m_overflowed == true)
return; return;

View File

@ -21,6 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define DEBUG_HEADER #define DEBUG_HEADER
#include <stdio.h> #include <stdio.h>
#include <jmutex.h>
#include <jmutexautolock.h>
#include <iostream> #include <iostream>
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "threads.h" #include "threads.h"
@ -37,6 +39,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#else #else
#endif #endif
using namespace jthread;
/* /*
Debug output Debug output
*/ */
@ -125,7 +129,7 @@ extern Nullstream dummyout;
Assert Assert
*/ */
extern void assert_fail( __NORETURN extern void assert_fail(
const char *assertion, const char *file, const char *assertion, const char *file,
unsigned int line, const char *function); unsigned int line, const char *function);
@ -155,7 +159,7 @@ struct DebugStack
}; };
extern core::map<threadid_t, DebugStack*> g_debug_stacks; extern core::map<threadid_t, DebugStack*> g_debug_stacks;
extern SimpleMutex g_debug_stacks_mutex; extern JMutex g_debug_stacks_mutex;
extern void debug_stacks_init(); extern void debug_stacks_init();
extern void debug_stacks_print(); extern void debug_stacks_print();

View File

@ -561,7 +561,7 @@ HTTPClient::HTTPClient(Client *client):
m_thread(this) m_thread(this)
{ {
m_client = client; m_client = client;
m_req_mutex.init(); m_req_mutex.Init();
} }
/* destructor */ /* destructor */
@ -613,24 +613,24 @@ void HTTPClient::step()
std::vector<HTTPRequest> p; std::vector<HTTPRequest> p;
m_req_mutex.lock(); m_req_mutex.Lock();
p.swap(m_requests); p.swap(m_requests);
m_req_mutex.unlock(); m_req_mutex.Unlock();
for (std::vector<HTTPRequest>::iterator i = p.begin(); i != p.end(); ++i) { for (std::vector<HTTPRequest>::iterator i = p.begin(); i != p.end(); ++i) {
HTTPRequest q = *i; HTTPRequest q = *i;
m_socket = new TCPSocket(); m_socket = new TCPSocket();
if (m_socket == NULL) { if (m_socket == NULL) {
m_req_mutex.lock(); m_req_mutex.Lock();
m_requests.push_back(q); m_requests.push_back(q);
m_req_mutex.unlock(); m_req_mutex.Unlock();
continue; continue;
} }
if (m_socket->Connect(m_address) == false) { if (m_socket->Connect(m_address) == false) {
delete m_socket; delete m_socket;
m_req_mutex.lock(); m_req_mutex.Lock();
m_requests.push_back(q); m_requests.push_back(q);
m_req_mutex.unlock(); m_req_mutex.Unlock();
m_connection_failures++; m_connection_failures++;
/* assume the server has no http */ /* assume the server has no http */
if (m_connection_failures > 4) { if (m_connection_failures > 4) {
@ -657,9 +657,9 @@ void HTTPClient::step()
h = m_recv_headers.read(m_socket); h = m_recv_headers.read(m_socket);
if (h == -1 || m_recv_headers.getResponse() == 500) { if (h == -1 || m_recv_headers.getResponse() == 500) {
delete m_socket; delete m_socket;
m_req_mutex.lock(); m_req_mutex.Lock();
m_requests.push_back(q); m_requests.push_back(q);
m_req_mutex.unlock(); m_req_mutex.Unlock();
continue; continue;
} }
@ -757,9 +757,9 @@ void HTTPClient::pushRequest(HTTPRequestType type, std::string &data)
url += data + "/skin"; url += data + "/skin";
HTTPRequest r(url); HTTPRequest r(url);
r.data = data; r.data = data;
m_req_mutex.lock(); m_req_mutex.Lock();
m_requests.push_back(r); m_requests.push_back(r);
m_req_mutex.unlock(); m_req_mutex.Unlock();
break; break;
} }
/* /*
@ -795,9 +795,9 @@ void HTTPClient::pushRequest(HTTPRequestType type, std::string &data)
url += data + "/skin/hash/" + buff; url += data + "/skin/hash/" + buff;
HTTPRequest r(url); HTTPRequest r(url);
r.data = data; r.data = data;
m_req_mutex.lock(); m_req_mutex.Lock();
m_requests.push_back(r); m_requests.push_back(r);
m_req_mutex.unlock(); m_req_mutex.Unlock();
break; break;
} }
/* /*
@ -819,9 +819,9 @@ void HTTPClient::pushRequest(HTTPRequestType type, std::string &data)
std::string url("/player/"); std::string url("/player/");
url += data + "/skin"; url += data + "/skin";
HTTPRequest r(url,ptex,data); HTTPRequest r(url,ptex,data);
m_req_mutex.lock(); m_req_mutex.Lock();
m_requests.push_back(r); m_requests.push_back(r);
m_req_mutex.unlock(); m_req_mutex.Unlock();
break; break;
} }
default:; default:;
@ -834,9 +834,9 @@ void HTTPClient::pushRequest(std::string &url, std::string &data)
if (m_thread.getRun() == false) if (m_thread.getRun() == false)
return; return;
HTTPRequest r(url,data); HTTPRequest r(url,data);
m_req_mutex.lock(); m_req_mutex.Lock();
m_requests.push_back(r); m_requests.push_back(r);
m_req_mutex.unlock(); m_req_mutex.Unlock();
} }
/* send a http GET request to the server */ /* send a http GET request to the server */

View File

@ -244,7 +244,7 @@ private:
HTTPRequestHeaders m_send_headers; HTTPRequestHeaders m_send_headers;
std::string m_cookie; std::string m_cookie;
std::vector<HTTPRequest> m_requests; std::vector<HTTPRequest> m_requests;
SimpleMutex m_req_mutex; JMutex m_req_mutex;
HTTPClientThread m_thread; HTTPClientThread m_thread;
Client *m_client; Client *m_client;
int m_connection_failures; int m_connection_failures;

View File

@ -0,0 +1,29 @@
if( UNIX )
set(jthread_SRCS pthread/jmutex.cpp pthread/jthread.cpp)
set(jthread_platform_LIBS "")
set(JTHREAD_CONFIG_WIN32THREADS "// Using pthread based threads")
set(JTHREAD_CONFIG_JMUTEXCRITICALSECTION "")
else( UNIX )
set(jthread_SRCS win32/jmutex.cpp win32/jthread.cpp)
set(jthread_platform_LIBS "")
set(JTHREAD_CONFIG_WIN32THREADS "#define JTHREAD_CONFIG_WIN32THREADS")
set(JTHREAD_WIN32_CRITICALSECTION OFF CACHE BOOL "If set to false, use standard mutex. If set to true, use a critical section object.")
if (JTHREAD_WIN32_CRITICALSECTION)
set(JTHREAD_CONFIG_JMUTEXCRITICALSECTION "#define JTHREAD_CONFIG_JMUTEXCRITICALSECTION")
else (JTHREAD_WIN32_CRITICALSECTION)
set(JTHREAD_CONFIG_JMUTEXCRITICALSECTION "// Using standard Win32 mutex")
endif (JTHREAD_WIN32_CRITICALSECTION)
endif( UNIX )
add_library(jthread ${jthread_SRCS})
target_link_libraries(
jthread
${jthread_platform_LIBS}
)
configure_file("${PROJECT_SOURCE_DIR}/jthread/jthreadconfig.h.in"
"${PROJECT_BINARY_DIR}/jthread/jthreadconfig.h")

20
src/jthread/LICENSE.MIT Normal file
View File

@ -0,0 +1,20 @@
The license of JThread:
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

75
src/jthread/jmutex.h Normal file
View File

@ -0,0 +1,75 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef JTHREAD_JMUTEX_H
#define JTHREAD_JMUTEX_H
#include "jthreadconfig.h"
#ifdef JTHREAD_CONFIG_WIN32THREADS
#ifndef _WIN32_WCE
#include <process.h>
#endif // _WIN32_WCE
#include <winsock2.h>
#include <windows.h>
#else // using pthread
#include <pthread.h>
#endif // JTHREAD_CONFIG_WIN32THREADS
#define ERR_JMUTEX_ALREADYINIT -1
#define ERR_JMUTEX_NOTINIT -2
#define ERR_JMUTEX_CANTCREATEMUTEX -3
namespace jthread
{
class JTHREAD_IMPORTEXPORT JMutex
{
public:
JMutex();
~JMutex();
int Init();
int Lock();
int Unlock();
bool IsInitialized() { return initialized; }
private:
#ifdef JTHREAD_CONFIG_WIN32THREADS
#ifdef JTHREAD_CONFIG_JMUTEXCRITICALSECTION
CRITICAL_SECTION mutex;
#else // Use standard mutex
HANDLE mutex;
#endif // JTHREAD_CONFIG_JMUTEXCRITICALSECTION
#else // pthread mutex
pthread_mutex_t mutex;
#endif // JTHREAD_CONFIG_WIN32THREADS
bool initialized;
};
} // end namespace
#endif // JTHREAD_JMUTEX_H

View File

@ -0,0 +1,50 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef JTHREAD_JMUTEXAUTOLOCK_H
#define JTHREAD_JMUTEXAUTOLOCK_H
#include "jthreadconfig.h"
#include "jmutex.h"
namespace jthread
{
class JTHREAD_IMPORTEXPORT JMutexAutoLock
{
public:
JMutexAutoLock(JMutex &m) : mutex(m) { mutex.Lock(); }
~JMutexAutoLock() { mutex.Unlock(); }
private:
JMutex &mutex;
};
} // end namespace
#endif // JTHREAD_JMUTEXAUTOLOCK_H

83
src/jthread/jthread.h Normal file
View File

@ -0,0 +1,83 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef JTHREAD_JTHREAD_H
#define JTHREAD_JTHREAD_H
#include "jthreadconfig.h"
#include "jmutex.h"
#define ERR_JTHREAD_CANTINITMUTEX -1
#define ERR_JTHREAD_CANTSTARTTHREAD -2
#define ERR_JTHREAD_THREADFUNCNOTSET -3
#define ERR_JTHREAD_NOTRUNNING -4
#define ERR_JTHREAD_ALREADYRUNNING -5
namespace jthread
{
class JTHREAD_IMPORTEXPORT JThread
{
public:
JThread();
virtual ~JThread();
int Start();
int Kill();
virtual void *Thread() = 0;
bool IsRunning();
void *GetReturnValue();
protected:
void ThreadStarted();
private:
#ifdef JTHREAD_CONFIG_WIN32THREADS
#ifdef _WIN32_WCE
DWORD threadid;
static DWORD WINAPI TheThread(void *param);
#else
static UINT __stdcall TheThread(void *param);
UINT threadid;
#endif // _WIN32_WCE
HANDLE threadhandle;
#else // pthread type threads
static void *TheThread(void *param);
pthread_t threadid;
#endif // JTHREAD_CONFIG_WIN32THREADS
void *retval;
bool running;
JMutex runningmutex;
JMutex continuemutex,continuemutex2;
bool mutexinit;
};
} // end namespace
#endif // JTHREAD_JTHREAD_H

View File

@ -0,0 +1,45 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#ifndef JTHREADCONFIG_H
#define JTHREADCONFIG_H
#define JTHREAD_IMPORT ${JTHREAD_IMPORT}
#define JTHREAD_EXPORT ${JTHREAD_EXPORT}
#ifdef JTHREAD_COMPILING
#define JTHREAD_IMPORTEXPORT JTHREAD_EXPORT
#else
#define JTHREAD_IMPORTEXPORT JTHREAD_IMPORT
#endif // JTHREAD_COMPILING
${JTHREAD_CONFIG_WIN32THREADS}
${JTHREAD_CONFIG_JMUTEXCRITICALSECTION}
#endif // JTHREADCONFIG_H

View File

@ -0,0 +1,73 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "jmutex.h"
namespace jthread
{
JMutex::JMutex()
{
initialized = false;
}
JMutex::~JMutex()
{
if (initialized)
pthread_mutex_destroy(&mutex);
}
int JMutex::Init()
{
if (initialized)
return ERR_JMUTEX_ALREADYINIT;
pthread_mutex_init(&mutex,NULL);
initialized = true;
return 0;
}
int JMutex::Lock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
pthread_mutex_lock(&mutex);
return 0;
}
int JMutex::Unlock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
pthread_mutex_unlock(&mutex);
return 0;
}
} // end namespace

View File

@ -0,0 +1,185 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "jthread.h"
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
namespace jthread
{
JThread::JThread()
{
retval = NULL;
mutexinit = false;
running = false;
}
JThread::~JThread()
{
Kill();
}
int JThread::Start()
{
int status;
if (!mutexinit)
{
if (!runningmutex.IsInitialized())
{
if (runningmutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex.IsInitialized())
{
if (continuemutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex2.IsInitialized())
{
if (continuemutex2.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
mutexinit = true;
}
runningmutex.Lock();
if (running)
{
runningmutex.Unlock();
return ERR_JTHREAD_ALREADYRUNNING;
}
runningmutex.Unlock();
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
continuemutex.Lock();
status = pthread_create(&threadid,&attr,TheThread,this);
pthread_attr_destroy(&attr);
if (status != 0)
{
continuemutex.Unlock();
return ERR_JTHREAD_CANTSTARTTHREAD;
}
/* Wait until 'running' is set */
runningmutex.Lock();
while (!running)
{
runningmutex.Unlock();
struct timespec req,rem;
req.tv_sec = 0;
req.tv_nsec = 1000000;
nanosleep(&req,&rem);
runningmutex.Lock();
}
runningmutex.Unlock();
continuemutex.Unlock();
continuemutex2.Lock();
continuemutex2.Unlock();
return 0;
}
int JThread::Kill()
{
runningmutex.Lock();
if (!running)
{
runningmutex.Unlock();
return ERR_JTHREAD_NOTRUNNING;
}
pthread_cancel(threadid);
running = false;
runningmutex.Unlock();
return 0;
}
bool JThread::IsRunning()
{
bool r;
runningmutex.Lock();
r = running;
runningmutex.Unlock();
return r;
}
void *JThread::GetReturnValue()
{
void *val;
runningmutex.Lock();
if (running)
val = NULL;
else
val = retval;
runningmutex.Unlock();
return val;
}
void *JThread::TheThread(void *param)
{
JThread *jthread;
void *ret;
jthread = (JThread *)param;
jthread->continuemutex2.Lock();
jthread->runningmutex.Lock();
jthread->running = true;
jthread->runningmutex.Unlock();
jthread->continuemutex.Lock();
jthread->continuemutex.Unlock();
ret = jthread->Thread();
jthread->runningmutex.Lock();
jthread->running = false;
jthread->retval = ret;
jthread->runningmutex.Unlock();
return NULL;
}
void JThread::ThreadStarted()
{
continuemutex2.Unlock();
}
} // end namespace

View File

@ -0,0 +1,87 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "jmutex.h"
namespace jthread
{
JMutex::JMutex()
{
initialized = false;
}
JMutex::~JMutex()
{
if (initialized)
#ifdef JTHREAD_CONFIG_JMUTEXCRITICALSECTION
DeleteCriticalSection(&mutex);
#else
CloseHandle(mutex);
#endif // JTHREAD_CONFIG_JMUTEXCRITICALSECTION
}
int JMutex::Init()
{
if (initialized)
return ERR_JMUTEX_ALREADYINIT;
#ifdef JTHREAD_CONFIG_JMUTEXCRITICALSECTION
InitializeCriticalSection(&mutex);
#else
mutex = CreateMutex(NULL,FALSE,NULL);
if (mutex == NULL)
return ERR_JMUTEX_CANTCREATEMUTEX;
#endif // JTHREAD_CONFIG_JMUTEXCRITICALSECTION
initialized = true;
return 0;
}
int JMutex::Lock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
#ifdef JTHREAD_CONFIG_JMUTEXCRITICALSECTION
EnterCriticalSection(&mutex);
#else
WaitForSingleObject(mutex,INFINITE);
#endif // JTHREAD_CONFIG_JMUTEXCRITICALSECTION
return 0;
}
int JMutex::Unlock()
{
if (!initialized)
return ERR_JMUTEX_NOTINIT;
#ifdef JTHREAD_CONFIG_JMUTEXCRITICALSECTION
LeaveCriticalSection(&mutex);
#else
ReleaseMutex(mutex);
#endif // JTHREAD_CONFIG_JMUTEXCRITICALSECTION
return 0;
}
} // end namespace

View File

@ -0,0 +1,182 @@
/*
This file is a part of the JThread package, which contains some object-
oriented thread wrappers for different thread implementations.
Copyright (c) 2000-2011 Jori Liesenborgs (jori.liesenborgs@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "jthread.h"
#include "jmutexautolock.h"
#ifndef _WIN32_WCE
#include <process.h>
#endif // _WIN32_WCE
namespace jthread
{
JThread::JThread()
{
retval = NULL;
mutexinit = false;
running = false;
}
JThread::~JThread()
{
Kill();
}
int JThread::Start()
{
if (!mutexinit)
{
if (!runningmutex.IsInitialized())
{
if (runningmutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex.IsInitialized())
{
if (continuemutex.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
}
if (!continuemutex2.IsInitialized())
{
if (continuemutex2.Init() < 0)
return ERR_JTHREAD_CANTINITMUTEX;
} mutexinit = true;
}
runningmutex.Lock();
if (running)
{
runningmutex.Unlock();
return ERR_JTHREAD_ALREADYRUNNING;
}
runningmutex.Unlock();
continuemutex.Lock();
#ifndef _WIN32_WCE
threadhandle = (HANDLE)_beginthreadex(NULL,0,TheThread,this,0,&threadid);
#else
threadhandle = CreateThread(NULL,0,TheThread,this,0,&threadid);
#endif // _WIN32_WCE
if (threadhandle == NULL)
{
continuemutex.Unlock();
return ERR_JTHREAD_CANTSTARTTHREAD;
}
/* Wait until 'running' is set */
runningmutex.Lock();
while (!running)
{
runningmutex.Unlock();
Sleep(1);
runningmutex.Lock();
}
runningmutex.Unlock();
continuemutex.Unlock();
continuemutex2.Lock();
continuemutex2.Unlock();
return 0;
}
int JThread::Kill()
{
runningmutex.Lock();
if (!running)
{
runningmutex.Unlock();
return ERR_JTHREAD_NOTRUNNING;
}
TerminateThread(threadhandle,0);
CloseHandle(threadhandle);
running = false;
runningmutex.Unlock();
return 0;
}
bool JThread::IsRunning()
{
bool r;
runningmutex.Lock();
r = running;
runningmutex.Unlock();
return r;
}
void *JThread::GetReturnValue()
{
JMutexAutoLock autolock(runningmutex);
void *val;
if (running)
val = NULL;
else
val = retval;
return val;
}
#ifndef _WIN32_WCE
UINT __stdcall JThread::TheThread(void *param)
#else
DWORD WINAPI JThread::TheThread(void *param)
#endif // _WIN32_WCE
{
JThread *jthread;
void *ret;
jthread = (JThread *)param;
jthread->continuemutex2.Lock();
jthread->runningmutex.Lock();
jthread->running = true;
jthread->runningmutex.Unlock();
jthread->continuemutex.Lock();
jthread->continuemutex.Unlock();
ret = jthread->Thread();
jthread->runningmutex.Lock();
jthread->running = false;
jthread->retval = ret;
CloseHandle(jthread->threadhandle);
jthread->runningmutex.Unlock();
return 0;
}
void JThread::ThreadStarted()
{
continuemutex2.Unlock();
}
} // end namespace

View File

@ -1013,15 +1013,15 @@ void SpeedTests()
dstream<<"Around 5000/ms should do well here."<<std::endl; dstream<<"Around 5000/ms should do well here."<<std::endl;
TimeTaker timer("Testing mutex speed"); TimeTaker timer("Testing mutex speed");
SimpleMutex m; JMutex m;
m.init(); m.Init();
u32 n = 0; u32 n = 0;
u32 i = 0; u32 i = 0;
do{ do{
n += 10000; n += 10000;
for(; i<n; i++){ for(; i<n; i++){
m.lock(); m.Lock();
m.unlock(); m.Unlock();
} }
} }
// Do at least 10ms // Do at least 10ms

View File

@ -2742,13 +2742,12 @@ std::string ServerMap::getSectorDir(v2s16 pos, int layout)
default: default:
assert(false); assert(false);
} }
return "";
} }
v2s16 ServerMap::getSectorPos(std::string dirname) v2s16 ServerMap::getSectorPos(std::string dirname)
{ {
unsigned int x, y; unsigned int x, y;
int r = 0; int r;
size_t spos = dirname.rfind(DIR_DELIM_C) + 1; size_t spos = dirname.rfind(DIR_DELIM_C) + 1;
assert(spos != std::string::npos); assert(spos != std::string::npos);
if(dirname.size() - spos == 8) if(dirname.size() - spos == 8)
@ -3504,7 +3503,8 @@ ClientMap::ClientMap(
m_camera_direction(0,0,1), m_camera_direction(0,0,1),
m_camera_fov(PI) m_camera_fov(PI)
{ {
m_camera_mutex.init(); m_camera_mutex.Init();
assert(m_camera_mutex.IsInitialized());
m_box = core::aabbox3d<f32>(-BS*1000000,-BS*1000000,-BS*1000000, m_box = core::aabbox3d<f32>(-BS*1000000,-BS*1000000,-BS*1000000,
BS*1000000,BS*1000000,BS*1000000); BS*1000000,BS*1000000,BS*1000000);
@ -3512,7 +3512,7 @@ ClientMap::ClientMap(
ClientMap::~ClientMap() ClientMap::~ClientMap()
{ {
/*SimpleMutexAutoLock lock(mesh_mutex); /*JMutexAutoLock lock(mesh_mutex);
if(mesh != NULL) if(mesh != NULL)
{ {
@ -3536,7 +3536,7 @@ MapSector * ClientMap::emergeSector(v2s16 p2d)
ClientMapSector *sector = new ClientMapSector(this, p2d); ClientMapSector *sector = new ClientMapSector(this, p2d);
{ {
//SimpleMutexAutoLock lock(m_sector_mutex); // Bulk comment-out //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
m_sectors.insert(p2d, sector); m_sectors.insert(p2d, sector);
} }
@ -3549,7 +3549,7 @@ void ClientMap::deSerializeSector(v2s16 p2d, std::istream &is)
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
ClientMapSector *sector = NULL; ClientMapSector *sector = NULL;
//SimpleMutexAutoLock lock(m_sector_mutex); // Bulk comment-out //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p2d); core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p2d);
@ -3562,7 +3562,7 @@ void ClientMap::deSerializeSector(v2s16 p2d, std::istream &is)
{ {
sector = new ClientMapSector(this, p2d); sector = new ClientMapSector(this, p2d);
{ {
//SimpleMutexAutoLock lock(m_sector_mutex); // Bulk comment-out //JMutexAutoLock lock(m_sector_mutex); // Bulk comment-out
m_sectors.insert(p2d, sector); m_sectors.insert(p2d, sector);
} }
} }
@ -3646,12 +3646,12 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
//u32 daynight_ratio = m_client->getDayNightRatio(); //u32 daynight_ratio = m_client->getDayNightRatio();
m_camera_mutex.lock(); m_camera_mutex.Lock();
v3f camera_position = m_camera_position; v3f camera_position = m_camera_position;
v3f camera_direction = m_camera_direction; v3f camera_direction = m_camera_direction;
f32 camera_fov = m_camera_fov; f32 camera_fov = m_camera_fov;
v3s16 camera_offset = m_camera_offset; v3s16 camera_offset = m_camera_offset;
m_camera_mutex.unlock(); m_camera_mutex.Unlock();
/* /*
Get all blocks and draw all visible ones Get all blocks and draw all visible ones
@ -3774,7 +3774,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
bool mesh_expired = false; bool mesh_expired = false;
{ {
SimpleMutexAutoLock lock(block->mesh_mutex); JMutexAutoLock lock(block->mesh_mutex);
mesh_expired = block->getMeshExpired(); mesh_expired = block->getMeshExpired();
@ -3859,7 +3859,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
Ignore if mesh doesn't exist Ignore if mesh doesn't exist
*/ */
{ {
SimpleMutexAutoLock lock(block->mesh_mutex); JMutexAutoLock lock(block->mesh_mutex);
MapBlockMesh *mesh = block->mesh; MapBlockMesh *mesh = block->mesh;
@ -3923,7 +3923,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
Draw the faces of the block Draw the faces of the block
*/ */
{ {
SimpleMutexAutoLock lock(block->mesh_mutex); JMutexAutoLock lock(block->mesh_mutex);
MapBlockMesh *mesh = block->mesh; MapBlockMesh *mesh = block->mesh;
assert(mesh); assert(mesh);
@ -4001,9 +4001,9 @@ void ClientMap::renderPostFx()
// Sadly ISceneManager has no "post effects" render pass, in that case we // Sadly ISceneManager has no "post effects" render pass, in that case we
// could just register for that and handle it in renderMap(). // could just register for that and handle it in renderMap().
m_camera_mutex.lock(); m_camera_mutex.Lock();
v3f camera_position = m_camera_position; v3f camera_position = m_camera_position;
m_camera_mutex.unlock(); m_camera_mutex.Unlock();
MapNode n = getNodeNoEx(floatToInt(camera_position, BS)); MapNode n = getNodeNoEx(floatToInt(camera_position, BS));
@ -4140,7 +4140,7 @@ void ClientMap::expireMeshes(bool only_daynight_diffed)
} }
{ {
SimpleMutexAutoLock lock(block->mesh_mutex); JMutexAutoLock lock(block->mesh_mutex);
if(block->mesh != NULL) if(block->mesh != NULL)
{ {
/*block->mesh->drop(); /*block->mesh->drop();

View File

@ -20,6 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAP_HEADER #ifndef MAP_HEADER
#define MAP_HEADER #define MAP_HEADER
#include <jmutex.h>
#include <jmutexautolock.h>
#include <jthread.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -28,13 +31,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock_nodemod.h" #include "mapblock_nodemod.h"
#include "constants.h" #include "constants.h"
#include "voxel.h" #include "voxel.h"
#include "porting.h"
#include "threads.h"
extern "C" { extern "C" {
#include "sqlite3.h" #include "sqlite3.h"
} }
using namespace jthread;
class MapSector; class MapSector;
class ServerMapSector; class ServerMapSector;
class ClientMapSector; class ClientMapSector;
@ -528,7 +531,7 @@ public:
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset) void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset)
{ {
SimpleMutexAutoLock lock(m_camera_mutex); JMutexAutoLock lock(m_camera_mutex);
m_camera_position = pos; m_camera_position = pos;
m_camera_direction = dir; m_camera_direction = dir;
m_camera_fov = fov; m_camera_fov = fov;
@ -607,7 +610,7 @@ private:
// This is the master heightmap mesh // This is the master heightmap mesh
//scene::SMesh *mesh; //scene::SMesh *mesh;
//SimpleMutex mesh_mutex; //JMutex mesh_mutex;
MapDrawControl &m_control; MapDrawControl &m_control;
@ -615,7 +618,7 @@ private:
v3f m_camera_direction; v3f m_camera_direction;
f32 m_camera_fov; f32 m_camera_fov;
v3s16 m_camera_offset; v3s16 m_camera_offset;
SimpleMutex m_camera_mutex; JMutex m_camera_mutex;
core::map<v2s16, bool> m_last_drawn_sectors; core::map<v2s16, bool> m_last_drawn_sectors;
}; };

View File

@ -47,9 +47,9 @@ MapBlock::MapBlock(Map *parent, v3s16 pos, bool dummy):
#ifndef SERVER #ifndef SERVER
m_mesh_expired = false; m_mesh_expired = false;
mesh_mutex.init(); mesh_mutex.Init();
mesh = NULL; mesh = NULL;
m_temp_mods_mutex.init(); m_temp_mods_mutex.Init();
#endif #endif
} }
@ -57,7 +57,7 @@ MapBlock::~MapBlock()
{ {
#ifndef SERVER #ifndef SERVER
{ {
SimpleMutexAutoLock lock(mesh_mutex); JMutexAutoLock lock(mesh_mutex);
if(mesh) if(mesh)
{ {
@ -142,7 +142,7 @@ void MapBlock::updateMesh(u32 daynight_ratio, Environment *env, v3s16 camera_off
DEBUG: If mesh has been generated, don't generate it again DEBUG: If mesh has been generated, don't generate it again
*/ */
{ {
SimpleMutexAutoLock meshlock(mesh_mutex); JMutexAutoLock meshlock(mesh_mutex);
if(mesh != NULL) if(mesh != NULL)
return; return;
} }
@ -167,7 +167,7 @@ void MapBlock::updateMesh(u32 daynight_ratio, Environment *env, v3s16 camera_off
void MapBlock::replaceMesh(MapBlockMesh *mesh_new) void MapBlock::replaceMesh(MapBlockMesh *mesh_new)
{ {
mesh_mutex.lock(); mesh_mutex.Lock();
//scene::SMesh *mesh_old = mesh[daynight_i]; //scene::SMesh *mesh_old = mesh[daynight_i];
//mesh[daynight_i] = mesh_new; //mesh[daynight_i] = mesh_new;
@ -202,7 +202,7 @@ void MapBlock::replaceMesh(MapBlockMesh *mesh_new)
delete mesh_old; delete mesh_old;
} }
mesh_mutex.unlock(); mesh_mutex.Unlock();
} }
#endif // !SERVER #endif // !SERVER

View File

@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAPBLOCK_HEADER #ifndef MAPBLOCK_HEADER
#define MAPBLOCK_HEADER #define MAPBLOCK_HEADER
#include <jmutex.h>
#include <jmutexautolock.h>
#include <exception> #include <exception>
#include "debug.h" #include "debug.h"
#include "common_irrlicht.h" #include "common_irrlicht.h"
@ -31,7 +33,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodemetadata.h" #include "nodemetadata.h"
#include "staticobject.h" #include "staticobject.h"
#include "mapblock_nodemod.h" #include "mapblock_nodemod.h"
#include "threads.h"
#ifndef SERVER #ifndef SERVER
#include "mapblock_mesh.h" #include "mapblock_mesh.h"
#endif #endif
@ -435,32 +436,32 @@ public:
<<", mod.type="<<mod.type <<", mod.type="<<mod.type
<<", mod.param="<<mod.param <<", mod.param="<<mod.param
<<std::endl;*/ <<std::endl;*/
SimpleMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
return m_temp_mods.set(p, mod); return m_temp_mods.set(p, mod);
} }
// Returns true if there was one // Returns true if there was one
bool getTempMod(v3s16 p, NodeMod *mod) bool getTempMod(v3s16 p, NodeMod *mod)
{ {
SimpleMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
return m_temp_mods.get(p, mod); return m_temp_mods.get(p, mod);
} }
bool clearTempMod(v3s16 p) bool clearTempMod(v3s16 p)
{ {
SimpleMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
return m_temp_mods.clear(p); return m_temp_mods.clear(p);
} }
bool clearTempMods() bool clearTempMods()
{ {
SimpleMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
return m_temp_mods.clear(); return m_temp_mods.clear();
} }
void copyTempMods(NodeModMap &dst) void copyTempMods(NodeModMap &dst)
{ {
SimpleMutexAutoLock lock(m_temp_mods_mutex); JMutexAutoLock lock(m_temp_mods_mutex);
m_temp_mods.copy(dst); m_temp_mods.copy(dst);
} }
#endif #endif
@ -571,7 +572,7 @@ public:
#ifndef SERVER // Only on client #ifndef SERVER // Only on client
MapBlockMesh *mesh; MapBlockMesh *mesh;
SimpleMutex mesh_mutex; JMutex mesh_mutex;
#endif #endif
NodeMetadataList m_node_metadata; NodeMetadataList m_node_metadata;
@ -635,7 +636,7 @@ private:
// Temporary modifications to nodes // Temporary modifications to nodes
// These are only used when drawing // These are only used when drawing
NodeModMap m_temp_mods; NodeModMap m_temp_mods;
SimpleMutex m_temp_mods_mutex; JMutex m_temp_mods_mutex;
#endif #endif
/* /*

View File

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "mapsector.h" #include "mapsector.h"
#include "jmutexautolock.h"
#include "client.h" #include "client.h"
#include "exceptions.h" #include "exceptions.h"
#include "mapblock.h" #include "mapblock.h"

View File

@ -24,11 +24,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef MAPSECTOR_HEADER #ifndef MAPSECTOR_HEADER
#define MAPSECTOR_HEADER #define MAPSECTOR_HEADER
#include <jmutex.h>
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "exceptions.h" #include "exceptions.h"
#include <ostream> #include <ostream>
#include "porting.h"
#include "threads.h"
class MapBlock; class MapBlock;
class Map; class Map;

View File

@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string> #include <string>
// Included for u32 and such // Included for u32 and such
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "debug.h"
#include "constants.h" #include "constants.h"
#ifdef _MSC_VER #ifdef _MSC_VER
@ -44,7 +45,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
# include <signal.h> # include <signal.h>
# define sleep_ms(x) usleep(x*1000) # define sleep_ms(x) usleep(x*1000)
#endif #endif
#include "debug.h"
namespace porting namespace porting
{ {

View File

@ -23,7 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include <string> #include <string>
#include "utility.h" #include "utility.h"
#include "threads.h" #include <jmutex.h>
#include <jmutexautolock.h>
/* /*
Time profiler Time profiler
@ -34,12 +35,12 @@ class Profiler
public: public:
Profiler() Profiler()
{ {
m_mutex.init(); m_mutex.Init();
} }
void add(const std::string &name, float value) void add(const std::string &name, float value)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
{ {
/* No average shall have been used; mark add used as -2 */ /* No average shall have been used; mark add used as -2 */
core::map<std::string, int>::Node *n = m_avgcounts.find(name); core::map<std::string, int>::Node *n = m_avgcounts.find(name);
@ -62,7 +63,7 @@ public:
void avg(const std::string &name, float value) void avg(const std::string &name, float value)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
{ {
core::map<std::string, int>::Node *n = m_avgcounts.find(name); core::map<std::string, int>::Node *n = m_avgcounts.find(name);
if(n == NULL) if(n == NULL)
@ -87,7 +88,7 @@ public:
void clear() void clear()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
for(core::map<std::string, float>::Iterator for(core::map<std::string, float>::Iterator
i = m_data.getIterator(); i = m_data.getIterator();
i.atEnd() == false; i++) i.atEnd() == false; i++)
@ -104,7 +105,7 @@ public:
void printPage(std::ostream &o, u32 page, u32 pagecount) void printPage(std::ostream &o, u32 page, u32 pagecount)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
u32 minindex, maxindex; u32 minindex, maxindex;
paging(m_data.size(), page, pagecount, minindex, maxindex); paging(m_data.size(), page, pagecount, minindex, maxindex);
@ -146,7 +147,7 @@ public:
} }
private: private:
SimpleMutex m_mutex; JMutex m_mutex;
core::map<std::string, float> m_data; core::map<std::string, float> m_data;
core::map<std::string, int> m_avgcounts; core::map<std::string, int> m_avgcounts;
}; };

View File

@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <iostream> #include <iostream>
#include "clientserver.h" #include "clientserver.h"
#include "map.h" #include "map.h"
#include "jmutexautolock.h"
#include "main.h" #include "main.h"
#include "constants.h" #include "constants.h"
#include "voxel.h" #include "voxel.h"
@ -40,7 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "profiler.h" #include "profiler.h"
#include "log.h" #include "log.h"
#include "base64.h" #include "base64.h"
#include "threads.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@ -73,7 +73,6 @@ private:
void * ServerThread::Thread() void * ServerThread::Thread()
{ {
printf("ServerThread::Thread()\n");
log_register_thread("ServerThread"); log_register_thread("ServerThread");
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -104,13 +103,12 @@ printf("ServerThread::Thread()\n");
END_DEBUG_EXCEPTION_HANDLER(errorstream) END_DEBUG_EXCEPTION_HANDLER(errorstream)
printf("ServerThread::Thread() exit\n");
return NULL; return NULL;
} }
void * EmergeThread::Thread() void * EmergeThread::Thread()
{ {
printf("EmergeThread::Thread()\n");
log_register_thread("EmergeThread"); log_register_thread("EmergeThread");
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -199,7 +197,7 @@ void * EmergeThread::Thread()
Fetch block from map or generate a single block Fetch block from map or generate a single block
*/ */
{ {
SimpleMutexAutoLock envlock(m_server->m_env_mutex); JMutexAutoLock envlock(m_server->m_env_mutex);
// Load sector if it isn't loaded // Load sector if it isn't loaded
if(map.getSectorNoGenerateNoEx(p2d) == NULL) if(map.getSectorNoGenerateNoEx(p2d) == NULL)
@ -266,7 +264,7 @@ void * EmergeThread::Thread()
} }
{//envlock {//envlock
SimpleMutexAutoLock envlock(m_server->m_env_mutex); JMutexAutoLock envlock(m_server->m_env_mutex);
if(got_block) if(got_block)
{ {
@ -311,7 +309,7 @@ void * EmergeThread::Thread()
*/ */
// NOTE: Server's clients are also behind the connection mutex // NOTE: Server's clients are also behind the connection mutex
SimpleMutexAutoLock lock(m_server->m_con_mutex); JMutexAutoLock lock(m_server->m_con_mutex);
/* /*
Add the originally fetched block to the modified list Add the originally fetched block to the modified list
@ -970,9 +968,9 @@ Server::Server(
m_emergethread_trigger_timer = 0.0; m_emergethread_trigger_timer = 0.0;
m_savemap_timer = 0.0; m_savemap_timer = 0.0;
m_env_mutex.init(); m_env_mutex.Init();
m_con_mutex.init(); m_con_mutex.Init();
m_step_dtime_mutex.init(); m_step_dtime_mutex.Init();
m_step_dtime = 0.0; m_step_dtime = 0.0;
// Register us to receive map edit events // Register us to receive map edit events
@ -998,7 +996,7 @@ Server::~Server()
Send shutdown message Send shutdown message
*/ */
{ {
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
std::wstring line = L"*** Server shutting down"; std::wstring line = L"*** Server shutting down";
@ -1024,7 +1022,7 @@ Server::~Server()
} }
{ {
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
/* /*
Save players Save players
@ -1048,7 +1046,7 @@ Server::~Server()
Delete clients Delete clients
*/ */
{ {
SimpleMutexAutoLock clientslock(m_con_mutex); JMutexAutoLock clientslock(m_con_mutex);
for(core::map<u16, RemoteClient*>::Iterator for(core::map<u16, RemoteClient*>::Iterator
i = m_clients.getIterator(); i = m_clients.getIterator();
@ -1058,7 +1056,7 @@ Server::~Server()
// NOTE: These are removed by env destructor // NOTE: These are removed by env destructor
{ {
u16 peer_id = i.getNode()->getKey(); u16 peer_id = i.getNode()->getKey();
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
m_env.removePlayer(peer_id); m_env.removePlayer(peer_id);
}*/ }*/
@ -1077,10 +1075,8 @@ void Server::start(unsigned short port)
// Initialize connection // Initialize connection
m_con.SetTimeoutMs(30); m_con.SetTimeoutMs(30);
m_con.Serve(port); m_con.Serve(port);
if (!m_con.getRun()) { if (!m_con.getRun())
printf("no con run\n");
return; return;
}
// Start thread // Start thread
m_thread.start(); m_thread.start();
@ -1110,7 +1106,7 @@ bool Server::step(float dtime)
if(dtime > 2.0) if(dtime > 2.0)
dtime = 2.0; dtime = 2.0;
{ {
SimpleMutexAutoLock lock(m_step_dtime_mutex); JMutexAutoLock lock(m_step_dtime_mutex);
m_step_dtime += dtime; m_step_dtime += dtime;
} }
return true; return true;
@ -1124,7 +1120,7 @@ void Server::AsyncRunStep()
float dtime; float dtime;
{ {
SimpleMutexAutoLock lock1(m_step_dtime_mutex); JMutexAutoLock lock1(m_step_dtime_mutex);
dtime = m_step_dtime; dtime = m_step_dtime;
} }
@ -1143,7 +1139,7 @@ void Server::AsyncRunStep()
//infostream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl; //infostream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl;
{ {
SimpleMutexAutoLock lock1(m_step_dtime_mutex); JMutexAutoLock lock1(m_step_dtime_mutex);
m_step_dtime -= dtime; m_step_dtime -= dtime;
} }
@ -1156,7 +1152,7 @@ void Server::AsyncRunStep()
{ {
// Process connection's timeouts // Process connection's timeouts
SimpleMutexAutoLock lock2(m_con_mutex); JMutexAutoLock lock2(m_con_mutex);
ScopeProfiler sp(g_profiler, "Server: connection timeout processing"); ScopeProfiler sp(g_profiler, "Server: connection timeout processing");
m_con.RunTimeouts(dtime); m_con.RunTimeouts(dtime);
} }
@ -1171,7 +1167,7 @@ void Server::AsyncRunStep()
Update m_time_of_day and overall game time Update m_time_of_day and overall game time
*/ */
{ {
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
m_time_counter += dtime; m_time_counter += dtime;
f32 speed = g_settings->getFloat("time_speed") * 24000./(24.*3600); f32 speed = g_settings->getFloat("time_speed") * 24000./(24.*3600);
@ -1191,8 +1187,8 @@ void Server::AsyncRunStep()
{ {
m_time_of_day_send_timer = g_settings->getFloat("time_send_interval"); m_time_of_day_send_timer = g_settings->getFloat("time_send_interval");
//SimpleMutexAutoLock envlock(m_env_mutex); //JMutexAutoLock envlock(m_env_mutex);
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
for(core::map<u16, RemoteClient*>::Iterator for(core::map<u16, RemoteClient*>::Iterator
i = m_clients.getIterator(); i = m_clients.getIterator();
@ -1210,7 +1206,7 @@ void Server::AsyncRunStep()
} }
{ {
SimpleMutexAutoLock lock(m_env_mutex); JMutexAutoLock lock(m_env_mutex);
// Step environment // Step environment
ScopeProfiler sp(g_profiler, "SEnv step"); ScopeProfiler sp(g_profiler, "SEnv step");
ScopeProfiler sp2(g_profiler, "SEnv step avg", SPT_AVG); ScopeProfiler sp2(g_profiler, "SEnv step avg", SPT_AVG);
@ -1220,7 +1216,7 @@ void Server::AsyncRunStep()
const float map_timer_and_unload_dtime = 2.92; const float map_timer_and_unload_dtime = 2.92;
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
{ {
SimpleMutexAutoLock lock(m_env_mutex); JMutexAutoLock lock(m_env_mutex);
// Run Map's timers and unload unused data // Run Map's timers and unload unused data
ScopeProfiler sp(g_profiler, "Server: map timer and unload"); ScopeProfiler sp(g_profiler, "Server: map timer and unload");
m_env.getMap().timerUpdate(map_timer_and_unload_dtime, m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
@ -1239,7 +1235,7 @@ void Server::AsyncRunStep()
{ {
m_liquid_transform_timer -= 1.00; m_liquid_transform_timer -= 1.00;
SimpleMutexAutoLock lock(m_env_mutex); JMutexAutoLock lock(m_env_mutex);
ScopeProfiler sp(g_profiler, "Server: liquid transform"); ScopeProfiler sp(g_profiler, "Server: liquid transform");
@ -1266,7 +1262,7 @@ void Server::AsyncRunStep()
Set the modified blocks unsent for all the clients Set the modified blocks unsent for all the clients
*/ */
SimpleMutexAutoLock lock2(m_con_mutex); JMutexAutoLock lock2(m_con_mutex);
for(core::map<u16, RemoteClient*>::Iterator for(core::map<u16, RemoteClient*>::Iterator
i = m_clients.getIterator(); i = m_clients.getIterator();
@ -1290,7 +1286,7 @@ void Server::AsyncRunStep()
{ {
counter = 0.0; counter = 0.0;
SimpleMutexAutoLock lock2(m_con_mutex); JMutexAutoLock lock2(m_con_mutex);
if(m_clients.size() != 0) if(m_clients.size() != 0)
infostream<<"Players:"<<std::endl; infostream<<"Players:"<<std::endl;
@ -1317,8 +1313,8 @@ void Server::AsyncRunStep()
*/ */
{ {
//infostream<<"Server: Checking added and deleted active objects"<<std::endl; //infostream<<"Server: Checking added and deleted active objects"<<std::endl;
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
ScopeProfiler sp(g_profiler, "Server: checking added and deleted objs"); ScopeProfiler sp(g_profiler, "Server: checking added and deleted objs");
@ -1466,8 +1462,8 @@ void Server::AsyncRunStep()
Send object messages Send object messages
*/ */
{ {
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
//ScopeProfiler sp(g_profiler, "Server: sending object messages"); //ScopeProfiler sp(g_profiler, "Server: sending object messages");
@ -1706,8 +1702,8 @@ void Server::AsyncRunStep()
counter += dtime; counter += dtime;
if(counter >= g_settings->getFloat("objectdata_interval")) if(counter >= g_settings->getFloat("objectdata_interval"))
{ {
SimpleMutexAutoLock lock1(m_env_mutex); JMutexAutoLock lock1(m_env_mutex);
SimpleMutexAutoLock lock2(m_con_mutex); JMutexAutoLock lock2(m_con_mutex);
//ScopeProfiler sp(g_profiler, "Server: sending player positions"); //ScopeProfiler sp(g_profiler, "Server: sending player positions");
@ -1751,7 +1747,7 @@ void Server::AsyncRunStep()
m_banmanager.save(); m_banmanager.save();
// Map // Map
SimpleMutexAutoLock lock(m_env_mutex); JMutexAutoLock lock(m_env_mutex);
/*// Unload unused data (delete from memory) /*// Unload unused data (delete from memory)
m_env.getMap().unloadUnusedData( m_env.getMap().unloadUnusedData(
@ -1787,7 +1783,7 @@ void Server::Receive()
u32 datasize; u32 datasize;
try{ try{
{ {
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
datasize = m_con.Receive(peer_id, data); datasize = m_con.Receive(peer_id, data);
} }
@ -1810,7 +1806,7 @@ void Server::Receive()
// The peer has been disconnected. // The peer has been disconnected.
// Find the associated player and remove it. // Find the associated player and remove it.
/*SimpleMutexAutoLock envlock(m_env_mutex); /*JMutexAutoLock envlock(m_env_mutex);
infostream<<"ServerThread: peer_id="<<peer_id infostream<<"ServerThread: peer_id="<<peer_id
<<" has apparently closed connection. " <<" has apparently closed connection. "
@ -1824,8 +1820,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
// Environment is locked first. // Environment is locked first.
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
try{ try{
Address address = m_con.GetPeerAddress(peer_id); Address address = m_con.GetPeerAddress(peer_id);
@ -2785,7 +2781,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
SendPlayerAnim(player,PLAYERANIM_STAND); SendPlayerAnim(player,PLAYERANIM_STAND);
#if 0 #if 0
RemoteClient *client = getClient(peer_id); RemoteClient *client = getClient(peer_id);
SimpleMutexAutoLock digmutex(client->m_dig_mutex); JMutexAutoLock digmutex(client->m_dig_mutex);
client->m_dig_tool_item = -1; client->m_dig_tool_item = -1;
#endif #endif
} }
@ -4508,8 +4504,8 @@ void Server::inventoryModified(InventoryContext *c, std::string id)
core::list<PlayerInfo> Server::getPlayerInfo() core::list<PlayerInfo> Server::getPlayerInfo()
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
core::list<PlayerInfo> list; core::list<PlayerInfo> list;
@ -4654,7 +4650,7 @@ void Server::SendPlayerInfos()
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
//SimpleMutexAutoLock envlock(m_env_mutex); //JMutexAutoLock envlock(m_env_mutex);
// Get connected players // Get connected players
core::list<Player*> players = m_env.getPlayers(true); core::list<Player*> players = m_env.getPlayers(true);
@ -4681,7 +4677,7 @@ void Server::SendPlayerInfos()
start += 2+PLAYERNAME_SIZE; start += 2+PLAYERNAME_SIZE;
} }
//SimpleMutexAutoLock conlock(m_con_mutex); //JMutexAutoLock conlock(m_con_mutex);
// Send as reliable // Send as reliable
m_con.SendToAll(0, data, true); m_con.SendToAll(0, data, true);
@ -5048,8 +5044,8 @@ void Server::SendBlocks(float dtime)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
//TimeTaker timer("Server::SendBlocks"); //TimeTaker timer("Server::SendBlocks");
@ -5201,7 +5197,7 @@ void Server::UpdateCrafting(u16 peer_id)
RemoteClient* Server::getClient(u16 peer_id) RemoteClient* Server::getClient(u16 peer_id)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
//SimpleMutexAutoLock lock(m_con_mutex); //JMutexAutoLock lock(m_con_mutex);
core::map<u16, RemoteClient*>::Node *n; core::map<u16, RemoteClient*>::Node *n;
n = m_clients.find(peer_id); n = m_clients.find(peer_id);
// A client should exist for all peers // A client should exist for all peers
@ -5422,8 +5418,8 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
void Server::handlePeerChange(PeerChange &c) void Server::handlePeerChange(PeerChange &c)
{ {
SimpleMutexAutoLock envlock(m_env_mutex); JMutexAutoLock envlock(m_env_mutex);
SimpleMutexAutoLock conlock(m_con_mutex); JMutexAutoLock conlock(m_con_mutex);
if(c.type == PEER_ADDED) if(c.type == PEER_ADDED)
{ {

View File

@ -54,12 +54,12 @@ class BlockEmergeQueue
public: public:
BlockEmergeQueue() BlockEmergeQueue()
{ {
m_mutex.init(); m_mutex.Init();
} }
~BlockEmergeQueue() ~BlockEmergeQueue()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::list<QueuedBlockEmerge*>::Iterator i; core::list<QueuedBlockEmerge*>::Iterator i;
for(i=m_queue.begin(); i!=m_queue.end(); i++) for(i=m_queue.begin(); i!=m_queue.end(); i++)
@ -76,7 +76,7 @@ public:
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
if(peer_id != 0) if(peer_id != 0)
{ {
@ -110,7 +110,7 @@ public:
// Returns NULL if queue is empty // Returns NULL if queue is empty
QueuedBlockEmerge * pop() QueuedBlockEmerge * pop()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin(); core::list<QueuedBlockEmerge*>::Iterator i = m_queue.begin();
if(i == m_queue.end()) if(i == m_queue.end())
@ -122,13 +122,13 @@ public:
u32 size() u32 size()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return m_queue.size(); return m_queue.size();
} }
u32 peerItemCount(u16 peer_id) u32 peerItemCount(u16 peer_id)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
u32 count = 0; u32 count = 0;
@ -145,7 +145,7 @@ public:
private: private:
core::list<QueuedBlockEmerge*> m_queue; core::list<QueuedBlockEmerge*> m_queue;
SimpleMutex m_mutex; JMutex m_mutex;
}; };
class Server; class Server;
@ -304,7 +304,7 @@ public:
// Time from last placing or removing blocks // Time from last placing or removing blocks
float m_time_from_building; float m_time_from_building;
/*SimpleMutex m_dig_mutex; /*JMutex m_dig_mutex;
float m_dig_time_remaining; float m_dig_time_remaining;
// -1 = not digging // -1 = not digging
s16 m_dig_tool_item; s16 m_dig_tool_item;
@ -604,11 +604,11 @@ private:
// Environment // Environment
ServerEnvironment m_env; ServerEnvironment m_env;
SimpleMutex m_env_mutex; JMutex m_env_mutex;
// Connection // Connection
con::Connection m_con; con::Connection m_con;
SimpleMutex m_con_mutex; JMutex m_con_mutex;
// Connected clients (behind the con mutex) // Connected clients (behind the con mutex)
core::map<u16, RemoteClient*> m_clients; core::map<u16, RemoteClient*> m_clients;
@ -625,7 +625,7 @@ private:
// A buffer for time steps // A buffer for time steps
// step() increments and AsyncRunStep() run by m_thread reads it. // step() increments and AsyncRunStep() run by m_thread reads it.
float m_step_dtime; float m_step_dtime;
SimpleMutex m_step_dtime_mutex; JMutex m_step_dtime_mutex;
// The server mainly operates in this thread // The server mainly operates in this thread
ServerThread m_thread; ServerThread m_thread;

View File

@ -52,6 +52,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <time.h> #include <time.h>
#include <jmutexautolock.h>
#include <locale.h> #include <locale.h>
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include "debug.h" #include "debug.h"
@ -77,7 +78,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content_craftitem.h" #include "content_craftitem.h"
#include "content_toolitem.h" #include "content_toolitem.h"
#include "http.h" #include "http.h"
#include "threads.h"
/* /*
Settings. Settings.

View File

@ -22,6 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common_irrlicht.h" #include "common_irrlicht.h"
#include <string> #include <string>
#include <jthread.h>
#include <jmutex.h>
#include <jmutexautolock.h>
#include "strfnd.h" #include "strfnd.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -29,7 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h" #include "debug.h"
#include "utility.h" #include "utility.h"
#include "log.h" #include "log.h"
#include "threads.h"
enum ValueType enum ValueType
{ {
@ -48,17 +50,19 @@ struct ValueSpec
const char *help; const char *help;
}; };
using namespace jthread;
class Settings class Settings
{ {
public: public:
Settings() Settings()
{ {
m_mutex.init(); m_mutex.Init();
} }
void writeLines(std::ostream &os) void writeLines(std::ostream &os)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
for(core::map<std::string, std::string>::Iterator for(core::map<std::string, std::string>::Iterator
i = m_settings.getIterator(); i = m_settings.getIterator();
@ -72,7 +76,7 @@ public:
bool parseConfigLine(const std::string &line) bool parseConfigLine(const std::string &line)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
std::string trimmedline = trim(line); std::string trimmedline = trim(line);
@ -172,7 +176,7 @@ public:
core::list<std::string> &dst, core::list<std::string> &dst,
core::map<std::string, bool> &updated) core::map<std::string, bool> &updated)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
if(is.eof()) if(is.eof())
return false; return false;
@ -256,7 +260,7 @@ public:
} }
} }
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
// Write stuff back // Write stuff back
{ {
@ -364,14 +368,14 @@ public:
void set(std::string name, std::string value) void set(std::string name, std::string value)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_settings[name] = value; m_settings[name] = value;
} }
void set(std::string name, const char *value) void set(std::string name, const char *value)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_settings[name] = value; m_settings[name] = value;
} }
@ -379,21 +383,21 @@ public:
void setDefault(std::string name, std::string value) void setDefault(std::string name, std::string value)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_defaults[name] = value; m_defaults[name] = value;
} }
bool exists(std::string name) bool exists(std::string name)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return (m_settings.find(name) || m_defaults.find(name)); return (m_settings.find(name) || m_defaults.find(name));
} }
std::string get(std::string name) std::string get(std::string name)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
core::map<std::string, std::string>::Node *n; core::map<std::string, std::string>::Node *n;
n = m_settings.find(name); n = m_settings.find(name);
@ -556,7 +560,7 @@ public:
void clear() void clear()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_settings.clear(); m_settings.clear();
m_defaults.clear(); m_defaults.clear();
@ -564,7 +568,7 @@ public:
void updateValue(Settings &other, const std::string &name) void updateValue(Settings &other, const std::string &name)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
if(&other == this) if(&other == this)
return; return;
@ -580,8 +584,8 @@ public:
void update(Settings &other) void update(Settings &other)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
SimpleMutexAutoLock lock2(other.m_mutex); JMutexAutoLock lock2(other.m_mutex);
if(&other == this) if(&other == this)
return; return;
@ -605,8 +609,8 @@ public:
Settings & operator+=(Settings &other) Settings & operator+=(Settings &other)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
SimpleMutexAutoLock lock2(other.m_mutex); JMutexAutoLock lock2(other.m_mutex);
if(&other == this) if(&other == this)
return *this; return *this;
@ -633,8 +637,8 @@ public:
Settings & operator=(Settings &other) Settings & operator=(Settings &other)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
SimpleMutexAutoLock lock2(other.m_mutex); JMutexAutoLock lock2(other.m_mutex);
if(&other == this) if(&other == this)
return *this; return *this;
@ -649,7 +653,7 @@ private:
core::map<std::string, std::string> m_settings; core::map<std::string, std::string> m_settings;
core::map<std::string, std::string> m_defaults; core::map<std::string, std::string> m_defaults;
// All methods that access m_settings/m_defaults directly should lock this. // All methods that access m_settings/m_defaults directly should lock this.
SimpleMutex m_mutex; JMutex m_mutex;
}; };
#endif #endif

View File

@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef THREADS_HEADER #ifndef THREADS_HEADER
#define THREADS_HEADER #define THREADS_HEADER
#include <jmutex.h>
#if (defined(WIN32) || defined(_WIN32_WCE)) #if (defined(WIN32) || defined(_WIN32_WCE))
typedef DWORD threadid_t; typedef DWORD threadid_t;
#define __NORETURN __declspec(noreturn) #define __NORETURN __declspec(noreturn)
@ -30,10 +32,6 @@ typedef pthread_t threadid_t;
#define __FUNCTION_NAME __PRETTY_FUNCTION__ #define __FUNCTION_NAME __PRETTY_FUNCTION__
#endif #endif
class SimpleMutex;
class SimpleThread;
#include "porting.h"
inline threadid_t get_current_thread_id() inline threadid_t get_current_thread_id()
{ {
#if (defined(WIN32) || defined(_WIN32_WCE)) #if (defined(WIN32) || defined(_WIN32_WCE))
@ -43,225 +41,5 @@ inline threadid_t get_current_thread_id()
#endif #endif
} }
/*
A simple mutex implementation
*/
#ifdef _WIN32
class SimpleMutex
{
CRITICAL_SECTION mut;
public:
SimpleMutex()
{
InitializeCriticalSection(&mut);
}
~SimpleMutex()
{
unlock();
DeleteCriticalSection(&mut);
}
void init()
{
InitializeCriticalSection(&mut);
}
void lock()
{
EnterCriticalSection(&mut);
}
bool trylock()
{
if (!TryEnterCriticalSection(&mut))
return true;
return false;
}
void unlock()
{
LeaveCriticalSection(&mut);
}
};
#else
class SimpleMutex
{
pthread_mutexattr_t attr;
pthread_mutex_t mut;
public:
SimpleMutex()
{
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mut, &attr);
}
~SimpleMutex()
{
unlock();
pthread_mutex_destroy(&mut);
pthread_mutexattr_destroy(&attr);
}
void init()
{
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mut, &attr);
}
void lock()
{
pthread_mutex_lock(&mut);
}
int trylock()
{
if (pthread_mutex_trylock(&mut))
return true;
return false;
}
void unlock()
{
pthread_mutex_unlock(&mut);
}
};
#endif
class SimpleMutexAutoLock
{
SimpleMutex &mutex;
public:
SimpleMutexAutoLock(SimpleMutex &m):
mutex(m)
{
mutex.lock();
}
~SimpleMutexAutoLock()
{
mutex.unlock();
}
};
/*
A base class for simple background thread implementation
*/
class SimpleThread
{
bool run;
SimpleMutex run_mutex;
#ifdef _WIN32
HANDLE thread;
#else
pthread_t thread;
pthread_attr_t attr;
#endif
public:
SimpleThread():
run(false),
run_mutex()
{
#ifndef _WIN32
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
#endif
}
virtual ~SimpleThread()
{
kill();
}
virtual void * Thread() = 0;
bool getRun()
{
run_mutex.lock();
bool r = run;
run_mutex.unlock();
return r;
}
void setRun(bool a_run)
{
run_mutex.lock();
run = a_run;
run_mutex.unlock();
}
void start()
{
if (getRun()) {
#ifdef _WIN32
ResumeThread(thread);
#else
pthread_kill(thread,SIGCONT);
#endif
}else{
setRun(true);
#ifdef _WIN32
thread = CreateThread(NULL, 0, &runThread, this, 0, NULL);
#else
pthread_create(&thread, &attr, &runThread, this);
#endif
}
}
void wait()
{
if (getRun()) {
#ifdef _WIN32
WaitForSingleObject(thread, 2000);
CloseHandle(thread);
#else
pthread_join(thread,NULL);
#endif
}
}
void stop()
{
setRun(false);
wait();
}
void kill()
{
if (getRun()) {
setRun(false);
#ifdef _WIN32
TerminateThread(thread,0);
CloseHandle(thread);
#else
pthread_kill(thread,SIGKILL);
#endif
}
}
private:
static void *runThread(void* data)
{
SimpleThread *t = (SimpleThread*)data;
void *r = t->Thread();
t->setRun(false);
#ifdef _WIN32
ExitThread(0);
CloseHandle(t->thread);
#else
pthread_exit(r);
#endif
return r;
}
};
#endif #endif

View File

@ -41,7 +41,7 @@ TextureSource::TextureSource(IrrlichtDevice *device):
{ {
assert(m_device); assert(m_device);
m_atlaspointer_cache_mutex.init(); m_atlaspointer_cache_mutex.Init();
m_main_thread = get_current_thread_id(); m_main_thread = get_current_thread_id();
@ -93,7 +93,7 @@ u32 TextureSource::getTextureId(const std::string &name)
/* /*
See if texture already exists See if texture already exists
*/ */
SimpleMutexAutoLock lock(m_atlaspointer_cache_mutex); JMutexAutoLock lock(m_atlaspointer_cache_mutex);
core::map<std::string, u32>::Node *n; core::map<std::string, u32>::Node *n;
n = m_name_to_id.find(name); n = m_name_to_id.find(name);
if(n != NULL) if(n != NULL)
@ -192,7 +192,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
See if texture already exists See if texture already exists
*/ */
{ {
SimpleMutexAutoLock lock(m_atlaspointer_cache_mutex); JMutexAutoLock lock(m_atlaspointer_cache_mutex);
core::map<std::string, u32>::Node *n; core::map<std::string, u32>::Node *n;
n = m_name_to_id.find(name); n = m_name_to_id.find(name);
@ -260,7 +260,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
// If a base image was found, copy it to baseimg // If a base image was found, copy it to baseimg
if(base_image_id != 0) if(base_image_id != 0)
{ {
SimpleMutexAutoLock lock(m_atlaspointer_cache_mutex); JMutexAutoLock lock(m_atlaspointer_cache_mutex);
SourceAtlasPointer ap = m_atlaspointer_cache[base_image_id]; SourceAtlasPointer ap = m_atlaspointer_cache[base_image_id];
@ -326,7 +326,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
Add texture to caches (add NULL textures too) Add texture to caches (add NULL textures too)
*/ */
SimpleMutexAutoLock lock(m_atlaspointer_cache_mutex); JMutexAutoLock lock(m_atlaspointer_cache_mutex);
u32 id = m_atlaspointer_cache.size(); u32 id = m_atlaspointer_cache.size();
AtlasPointer ap(id); AtlasPointer ap(id);
@ -349,7 +349,7 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
std::string TextureSource::getTextureName(u32 id) std::string TextureSource::getTextureName(u32 id)
{ {
SimpleMutexAutoLock lock(m_atlaspointer_cache_mutex); JMutexAutoLock lock(m_atlaspointer_cache_mutex);
if(id >= m_atlaspointer_cache.size()) if(id >= m_atlaspointer_cache.size())
{ {
@ -365,7 +365,7 @@ std::string TextureSource::getTextureName(u32 id)
AtlasPointer TextureSource::getTexture(u32 id) AtlasPointer TextureSource::getTexture(u32 id)
{ {
SimpleMutexAutoLock lock(m_atlaspointer_cache_mutex); JMutexAutoLock lock(m_atlaspointer_cache_mutex);
if(id >= m_atlaspointer_cache.size()) if(id >= m_atlaspointer_cache.size())
return AtlasPointer(0, NULL); return AtlasPointer(0, NULL);
@ -382,7 +382,7 @@ void TextureSource::buildMainAtlas()
video::IVideoDriver* driver = m_device->getVideoDriver(); video::IVideoDriver* driver = m_device->getVideoDriver();
assert(driver); assert(driver);
SimpleMutexAutoLock lock(m_atlaspointer_cache_mutex); JMutexAutoLock lock(m_atlaspointer_cache_mutex);
// Create an image of the right size // Create an image of the right size
core::dimension2d<u32> atlas_dim(4096,4096); core::dimension2d<u32> atlas_dim(4096,4096);

View File

@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "utility.h" #include "utility.h"
#include <string> #include <string>
using namespace jthread;
/* /*
tile.{h,cpp}: Texture handling stuff. tile.{h,cpp}: Texture handling stuff.
*/ */
@ -246,7 +248,7 @@ private:
// Maps a texture name to an index in the former. // Maps a texture name to an index in the former.
core::map<std::string, u32> m_name_to_id; core::map<std::string, u32> m_name_to_id;
// The two former containers are behind this mutex // The two former containers are behind this mutex
SimpleMutex m_atlaspointer_cache_mutex; JMutex m_atlaspointer_cache_mutex;
// Main texture atlas. This is filled at startup and is then not touched. // Main texture atlas. This is filled at startup and is then not touched.
video::IImage *m_main_atlas_image; video::IImage *m_main_atlas_image;

View File

@ -25,6 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <jthread.h>
#include <jmutex.h>
#include <jmutexautolock.h>
#include <cstring> #include <cstring>
#include "common_irrlicht.h" #include "common_irrlicht.h"
@ -32,7 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "strfnd.h" #include "strfnd.h"
#include "exceptions.h" #include "exceptions.h"
#include "porting.h" #include "porting.h"
#include "threads.h"
using namespace jthread;
extern const v3s16 g_6dirs[6]; extern const v3s16 g_6dirs[6];
@ -541,32 +545,32 @@ public:
MutexedVariable(T value): MutexedVariable(T value):
m_value(value) m_value(value)
{ {
m_mutex.init(); m_mutex.Init();
} }
T get() T get()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return m_value; return m_value;
} }
void set(T value) void set(T value)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_value = value; m_value = value;
} }
// You'll want to grab this in a SharedPtr // You'll want to grab this in a SharedPtr
SimpleMutex *getLock() JMutexAutoLock * getLock()
{ {
return new SimpleMutexAutoLock(m_mutex); return new JMutexAutoLock(m_mutex);
} }
// You pretty surely want to grab the lock when accessing this // You pretty surely want to grab the lock when accessing this
T m_value; T m_value;
private: private:
SimpleMutex m_mutex; JMutex m_mutex;
}; };
/* /*
@ -968,6 +972,197 @@ inline void str_replace_char(std::string & str, char from, char to)
} }
} }
/*
A simple mutex implementation
*/
#ifdef _WIN32
class SimpleMutex
{
CRITICAL_SECTION mut;
public:
SimpleMutex()
{
InitializeCriticalSection(&mut);
}
~SimpleMutex()
{
unlock();
DeleteCriticalSection(&mut);
}
void lock()
{
EnterCriticalSection(&mut);
}
bool trylock()
{
if (!TryEnterCriticalSection(&mut))
return true;
return false;
}
void unlock()
{
LeaveCriticalSection(&mut);
}
};
#else
class SimpleMutex
{
pthread_mutexattr_t attr;
pthread_mutex_t mut;
public:
SimpleMutex()
{
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mut, &attr);
}
~SimpleMutex()
{
unlock();
pthread_mutex_destroy(&mut);
pthread_mutexattr_destroy(&attr);
}
void lock()
{
pthread_mutex_lock(&mut);
}
int trylock()
{
if (pthread_mutex_trylock(&mut))
return true;
return false;
}
void unlock()
{
pthread_mutex_unlock(&mut);
}
};
#endif
/*
A base class for simple background thread implementation
*/
class SimpleThread
{
bool run;
SimpleMutex run_mutex;
#ifdef _WIN32
HANDLE thread;
#else
pthread_t thread;
pthread_attr_t attr;
#endif
public:
SimpleThread():
run(false),
run_mutex()
{
#ifndef _WIN32
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
#endif
}
virtual ~SimpleThread()
{
kill();
}
virtual void * Thread() = 0;
bool getRun()
{
run_mutex.lock();
bool r = run;
run_mutex.unlock();
return r;
}
void setRun(bool a_run)
{
run_mutex.lock();
run = a_run;
run_mutex.unlock();
}
void start()
{
if (getRun()) {
#ifdef _WIN32
ResumeThread(thread);
#else
pthread_kill(thread,SIGCONT);
#endif
}else{
setRun(true);
#ifdef _WIN32
thread = CreateThread(NULL, 0, &runThread, this, 0, NULL);
#else
pthread_create(&thread, &attr, &runThread, this);
#endif
}
}
void wait()
{
if (getRun()) {
#ifdef _WIN32
WaitForSingleObject(thread, 2000);
CloseHandle(thread);
#else
pthread_join(thread,NULL);
#endif
}
}
void stop()
{
setRun(false);
wait();
}
void kill()
{
if (getRun()) {
setRun(false);
#ifdef _WIN32
TerminateThread(thread,0);
CloseHandle(thread);
#else
pthread_kill(thread,SIGKILL);
#endif
}
}
private:
static void *runThread(void* data)
{
SimpleThread *t = (SimpleThread*)data;
void *r = t->Thread();
t->setRun(false);
#ifdef _WIN32
ExitThread(0);
CloseHandle(t->thread);
#else
pthread_exit(r);
#endif
return r;
}
};
/* /*
FIFO queue (well, actually a FILO also) FIFO queue (well, actually a FILO also)
*/ */
@ -1020,16 +1215,16 @@ class MutexedQueue
public: public:
MutexedQueue() MutexedQueue()
{ {
m_mutex.init(); m_mutex.Init();
} }
u32 size() u32 size()
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
return m_list.size(); return m_list.size();
} }
void push_back(T t) void push_back(T t)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_list.push_back(t); m_list.push_back(t);
} }
T pop_front(u32 wait_time_max_ms=0) T pop_front(u32 wait_time_max_ms=0)
@ -1039,7 +1234,7 @@ public:
for(;;) for(;;)
{ {
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
if(m_list.size() > 0) if(m_list.size() > 0)
{ {
@ -1065,7 +1260,7 @@ public:
for(;;) for(;;)
{ {
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
if(m_list.size() > 0) if(m_list.size() > 0)
{ {
@ -1085,7 +1280,7 @@ public:
} }
} }
SimpleMutex & getMutex() JMutex & getMutex()
{ {
return m_mutex; return m_mutex;
} }
@ -1096,7 +1291,7 @@ public:
} }
protected: protected:
SimpleMutex m_mutex; JMutex m_mutex;
core::list<T> m_list; core::list<T> m_list;
}; };
@ -1165,7 +1360,7 @@ public:
void add(Key key, Caller caller, CallerData callerdata, void add(Key key, Caller caller, CallerData callerdata,
ResultQueue<Key, T, Caller, CallerData> *dest) ResultQueue<Key, T, Caller, CallerData> *dest)
{ {
SimpleMutexAutoLock lock(m_queue.getMutex()); JMutexAutoLock lock(m_queue.getMutex());
/* /*
If the caller is already on the list, only update CallerData If the caller is already on the list, only update CallerData
@ -1292,18 +1487,20 @@ class MutexedMap
public: public:
MutexedMap() MutexedMap()
{ {
m_mutex.init(); m_mutex.Init();
assert(m_mutex.IsInitialized());
} }
void set(const Key &name, const Value &value) void set(const Key &name, const Value &value)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
m_values[name] = value; m_values[name] = value;
} }
bool get(const Key &name, Value *result) bool get(const Key &name, Value *result)
{ {
SimpleMutexAutoLock lock(m_mutex); JMutexAutoLock lock(m_mutex);
typename core::map<Key, Value>::Node *n; typename core::map<Key, Value>::Node *n;
n = m_values.find(name); n = m_values.find(name);
@ -1319,7 +1516,7 @@ public:
private: private:
core::map<Key, Value> m_values; core::map<Key, Value> m_values;
SimpleMutex m_mutex; JMutex m_mutex;
}; };
#endif #endif
@ -1341,7 +1538,8 @@ class MutexedIdGenerator
public: public:
MutexedIdGenerator() MutexedIdGenerator()
{ {
m_mutex.init(); m_mutex.Init();
assert(m_mutex.IsInitialized());
} }
// Returns true if found // Returns true if found
@ -1349,7 +1547,7 @@ public:
{ {
if(id == 0) if(id == 0)
return false; return false;
SimpleMutexAutoLock(m_mutex); JMutexAutoLock lock(m_mutex);
if(m_id_to_value.size() < id) if(m_id_to_value.size() < id)
return false; return false;
value = m_id_to_value[id-1]; value = m_id_to_value[id-1];
@ -1360,7 +1558,7 @@ public:
// Otherwise generates an id for the value. // Otherwise generates an id for the value.
u32 getId(const T &value) u32 getId(const T &value)
{ {
SimpleMutexAutoLock(m_mutex); JMutexAutoLock lock(m_mutex);
typename core::map<T, u32>::Node *n; typename core::map<T, u32>::Node *n;
n = m_value_to_id.find(value); n = m_value_to_id.find(value);
if(n != NULL) if(n != NULL)
@ -1372,7 +1570,7 @@ public:
} }
private: private:
SimpleMutex m_mutex; JMutex m_mutex;
// Values are stored here at id-1 position (id 1 = [0]) // Values are stored here at id-1 position (id 1 = [0])
core::array<T> m_id_to_value; core::array<T> m_id_to_value;
core::map<T, u32> m_value_to_id; core::map<T, u32> m_value_to_id;