Changeset - r23587:821735a25dec
[Not reviewed]
projects/openttd_vs140.vcxproj
Show inline comments
 
@@ -1334,8 +1334,7 @@
 
    <ResourceCompile Include="..\src\os\windows\ottdres.rc" />
 
    <ClCompile Include="..\src\os\windows\string_uniscribe.cpp" />
 
    <ClCompile Include="..\src\os\windows\win32.cpp" />
 
    <ClInclude Include="..\src\thread\thread.h" />
 
    <ClCompile Include="..\src\thread\thread_win32.cpp" />
 
    <ClInclude Include="..\src\thread.h" />
 
  </ItemGroup>
 
  <ItemGroup>
 
    <None Include="..\media\openttd.ico" />
projects/openttd_vs140.vcxproj.filters
Show inline comments
 
@@ -3090,12 +3090,9 @@
 
    <ClCompile Include="..\src\os\windows\win32.cpp">
 
      <Filter>Windows files</Filter>
 
    </ClCompile>
 
    <ClInclude Include="..\src\thread\thread.h">
 
    <ClInclude Include="..\src\thread.h">
 
      <Filter>Threading</Filter>
 
    </ClInclude>
 
    <ClCompile Include="..\src\thread\thread_win32.cpp">
 
      <Filter>Threading</Filter>
 
    </ClCompile>
 
  </ItemGroup>
 
  <ItemGroup>
 
    <None Include="..\media\openttd.ico" />
projects/openttd_vs141.vcxproj
Show inline comments
 
@@ -1334,8 +1334,7 @@
 
    <ResourceCompile Include="..\src\os\windows\ottdres.rc" />
 
    <ClCompile Include="..\src\os\windows\string_uniscribe.cpp" />
 
    <ClCompile Include="..\src\os\windows\win32.cpp" />
 
    <ClInclude Include="..\src\thread\thread.h" />
 
    <ClCompile Include="..\src\thread\thread_win32.cpp" />
 
    <ClInclude Include="..\src\thread.h" />
 
  </ItemGroup>
 
  <ItemGroup>
 
    <None Include="..\media\openttd.ico" />
projects/openttd_vs141.vcxproj.filters
Show inline comments
 
@@ -3090,12 +3090,9 @@
 
    <ClCompile Include="..\src\os\windows\win32.cpp">
 
      <Filter>Windows files</Filter>
 
    </ClCompile>
 
    <ClInclude Include="..\src\thread\thread.h">
 
    <ClInclude Include="..\src\thread.h">
 
      <Filter>Threading</Filter>
 
    </ClInclude>
 
    <ClCompile Include="..\src\thread\thread_win32.cpp">
 
      <Filter>Threading</Filter>
 
    </ClCompile>
 
  </ItemGroup>
 
  <ItemGroup>
 
    <None Include="..\media\openttd.ico" />
projects/openttd_vs142.vcxproj
Show inline comments
 
@@ -1334,8 +1334,7 @@
 
    <ResourceCompile Include="..\src\os\windows\ottdres.rc" />
 
    <ClCompile Include="..\src\os\windows\string_uniscribe.cpp" />
 
    <ClCompile Include="..\src\os\windows\win32.cpp" />
 
    <ClInclude Include="..\src\thread\thread.h" />
 
    <ClCompile Include="..\src\thread\thread_win32.cpp" />
 
    <ClInclude Include="..\src\thread.h" />
 
  </ItemGroup>
 
  <ItemGroup>
 
    <None Include="..\media\openttd.ico" />
projects/openttd_vs142.vcxproj.filters
Show inline comments
 
@@ -3090,12 +3090,9 @@
 
    <ClCompile Include="..\src\os\windows\win32.cpp">
 
      <Filter>Windows files</Filter>
 
    </ClCompile>
 
    <ClInclude Include="..\src\thread\thread.h">
 
    <ClInclude Include="..\src\thread.h">
 
      <Filter>Threading</Filter>
 
    </ClInclude>
 
    <ClCompile Include="..\src\thread\thread_win32.cpp">
 
      <Filter>Threading</Filter>
 
    </ClCompile>
 
  </ItemGroup>
 
  <ItemGroup>
 
    <None Include="..\media\openttd.ico" />
source.list
Show inline comments
 
@@ -1173,17 +1173,4 @@ sound/null_s.cpp
 
#end
 

	
 
# Threading
 
thread/thread.h
 
#if USE_THREADS
 
	#if WIN32
 
		thread/thread_win32.cpp
 
	#else
 
		#if OS2
 
			thread/thread_os2.cpp
 
		#else
 
			thread/thread_pthread.cpp
 
		#end
 
	#end
 
#else
 
	thread/thread_none.cpp
 
#end
 
thread.h
src/genworld.cpp
Show inline comments
 
@@ -34,7 +34,7 @@
 
#include "game/game.hpp"
 
#include "game/game_instance.hpp"
 
#include "string_func.h"
 
#include "thread/thread.h"
 
#include "thread.h"
 

	
 
#include "safeguards.h"
 

	
 
@@ -94,7 +94,7 @@ static void CleanupGeneration()
 
/**
 
 * The internal, real, generate function.
 
 */
 
static void _GenerateWorld(void *)
 
static void _GenerateWorld()
 
{
 
	/* Make sure everything is done via OWNER_NONE. */
 
	Backup<CompanyByte> _cur_company(_current_company, OWNER_NONE, FILE_LINE);
 
@@ -242,14 +242,12 @@ void GenerateWorldSetAbortCallback(GWAbo
 
 */
 
void WaitTillGeneratedWorld()
 
{
 
	if (_gw.thread == NULL) return;
 
	if (!_gw.thread.joinable()) return;
 

	
 
	_modal_progress_work_mutex.unlock();
 
	_modal_progress_paint_mutex.unlock();
 
	_gw.quit_thread = true;
 
	_gw.thread->Join();
 
	delete _gw.thread;
 
	_gw.thread   = NULL;
 
	_gw.thread.join();
 
	_gw.threaded = false;
 
	_modal_progress_work_mutex.lock();
 
	_modal_progress_paint_mutex.lock();
 
@@ -284,7 +282,7 @@ void HandleGeneratingWorldAbortion()
 

	
 
	CleanupGeneration();
 

	
 
	if (_gw.thread != NULL) _gw.thread->Exit();
 
	if (_gw.thread.joinable() && _gw.thread.get_id() == std::this_thread::get_id()) throw OTTDThreadExitSignal();
 

	
 
	SwitchToMode(_switch_mode);
 
}
 
@@ -326,17 +324,13 @@ void GenerateWorld(GenWorldMode mode, ui
 
	SetupColoursAndInitialWindow();
 
	SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
 

	
 
	if (_gw.thread != NULL) {
 
		_gw.thread->Join();
 
		delete _gw.thread;
 
		_gw.thread = NULL;
 
	}
 
	if (_gw.thread.joinable()) _gw.thread.join();
 

	
 
	if (!UseThreadedModelProgress() || !VideoDriver::GetInstance()->HasGUI() || !ThreadObject::New(&_GenerateWorld, NULL, &_gw.thread, "ottd:genworld")) {
 
	if (!UseThreadedModelProgress() || !VideoDriver::GetInstance()->HasGUI() || !StartNewThread(&_gw.thread, "ottd:genworld", &_GenerateWorld)) {
 
		DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
 
		_gw.threaded = false;
 
		_modal_progress_work_mutex.unlock();
 
		_GenerateWorld(NULL);
 
		_GenerateWorld();
 
		_modal_progress_work_mutex.lock();
 
		return;
 
	}
src/genworld.h
Show inline comments
 
@@ -13,6 +13,7 @@
 
#define GENWORLD_H
 

	
 
#include "company_type.h"
 
#include <thread>
 

	
 
/** Constants related to world generation */
 
enum LandscapeGenerator {
 
@@ -61,7 +62,7 @@ struct GenWorldInfo {
 
	uint size_y;           ///< Y-size of the map
 
	GWDoneProc *proc;      ///< Proc that is called when done (can be NULL)
 
	GWAbortProc *abortp;   ///< Proc that is called when aborting (can be NULL)
 
	class ThreadObject *thread; ///< The thread we are in (can be NULL)
 
	std::thread thread;    ///< The thread we are in (joinable if a thread was created)
 
};
 

	
 
/** Current stage of world generation process */
src/linkgraph/linkgraphjob.cpp
Show inline comments
 
@@ -39,7 +39,6 @@ LinkGraphJob::LinkGraphJob(const LinkGra
 
		 * This is on purpose. */
 
		link_graph(orig),
 
		settings(_settings_game.linkgraph),
 
		thread(NULL),
 
		join_date(_date + _settings_game.linkgraph.recalc_time)
 
{
 
}
 
@@ -61,8 +60,7 @@ void LinkGraphJob::EraseFlows(NodeID fro
 
 */
 
void LinkGraphJob::SpawnThread()
 
{
 
	if (!ThreadObject::New(&(LinkGraphSchedule::Run), this, &this->thread, "ottd:linkgraph")) {
 
		this->thread = NULL;
 
	if (!StartNewThread(&this->thread, "ottd:linkgraph", &(LinkGraphSchedule::Run), this)) {
 
		/* Of course this will hang a bit.
 
		 * On the other hand, if you want to play games which make this hang noticably
 
		 * on a platform without threads then you'll probably get other problems first.
 
@@ -79,10 +77,8 @@ void LinkGraphJob::SpawnThread()
 
 */
 
void LinkGraphJob::JoinThread()
 
{
 
	if (this->thread != NULL) {
 
		this->thread->Join();
 
		delete this->thread;
 
		this->thread = NULL;
 
	if (this->thread.joinable()) {
 
		this->thread.join();
 
	}
 
}
 

	
src/linkgraph/linkgraphjob.h
Show inline comments
 
@@ -12,7 +12,7 @@
 
#ifndef LINKGRAPHJOB_H
 
#define LINKGRAPHJOB_H
 

	
 
#include "../thread/thread.h"
 
#include "../thread.h"
 
#include "linkgraph.h"
 
#include <list>
 

	
 
@@ -59,7 +59,7 @@ private:
 
protected:
 
	const LinkGraph link_graph;       ///< Link graph to by analyzed. Is copied when job is started and mustn't be modified later.
 
	const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time.
 
	ThreadObject *thread;             ///< Thread the job is running in or NULL if it's running in the main thread.
 
	std::thread thread;               ///< Thread the job is running in or a default-constructed thread if it's running in the main thread.
 
	Date join_date;                   ///< Date when the job is to be joined.
 
	NodeAnnotationVector nodes;       ///< Extra node data necessary for link graph calculation.
 
	EdgeAnnotationMatrix edges;       ///< Extra edge data necessary for link graph calculation.
 
@@ -266,7 +266,7 @@ public:
 
	 * Bare constructor, only for save/load. link_graph, join_date and actually
 
	 * settings have to be brutally const-casted in order to populate them.
 
	 */
 
	LinkGraphJob() : settings(_settings_game.linkgraph), thread(NULL),
 
	LinkGraphJob() : settings(_settings_game.linkgraph),
 
			join_date(INVALID_DATE) {}
 

	
 
	LinkGraphJob(const LinkGraph &orig);
src/linkgraph/linkgraphschedule.cpp
Show inline comments
 
@@ -69,13 +69,11 @@ void LinkGraphSchedule::JoinNext()
 
}
 

	
 
/**
 
 * Run all handlers for the given Job. This method is tailored to
 
 * ThreadObject::New.
 
 * @param j Pointer to a link graph job.
 
 * Run all handlers for the given Job.
 
 * @param job Pointer to a link graph job.
 
 */
 
/* static */ void LinkGraphSchedule::Run(void *j)
 
/* static */ void LinkGraphSchedule::Run(LinkGraphJob *job)
 
{
 
	LinkGraphJob *job = (LinkGraphJob *)j;
 
	for (uint i = 0; i < lengthof(instance.handlers); ++i) {
 
		instance.handlers[i]->Run(*job);
 
	}
src/linkgraph/linkgraphschedule.h
Show inline comments
 
@@ -53,7 +53,7 @@ public:
 
	static const uint SPAWN_JOIN_TICK = 21; ///< Tick when jobs are spawned or joined every day.
 
	static LinkGraphSchedule instance;
 

	
 
	static void Run(void *j);
 
	static void Run(LinkGraphJob *job);
 
	static void Clear();
 

	
 
	void SpawnNext();
src/music/dmusic.cpp
Show inline comments
 
@@ -19,7 +19,7 @@
 
#include "../debug.h"
 
#include "../os/windows/win32.h"
 
#include "../core/mem_func.hpp"
 
#include "../thread/thread.h"
 
#include "../thread.h"
 
#include "../fileio_func.h"
 
#include "../base_media_base.h"
 
#include "dmusic.h"
 
@@ -139,7 +139,7 @@ static struct {
 
} _playback;
 

	
 
/** Handle to our worker thread. */
 
static ThreadObject *_dmusic_thread = NULL;
 
static std::thread _dmusic_thread;
 
/** Event to signal the thread that it should look at a state change. */
 
static HANDLE _thread_event = NULL;
 
/** Lock access to playback data that is not thread-safe. */
 
@@ -597,7 +597,7 @@ static void TransmitNotesOff(IDirectMusi
 
	Sleep(Clamp((block_time - cur_time) / MS_TO_REFTIME, 5, 1000));
 
}
 

	
 
static void MidiThreadProc(void *)
 
static void MidiThreadProc()
 
{
 
	DEBUG(driver, 2, "DMusic: Entering playback thread");
 

	
 
@@ -1169,7 +1169,7 @@ const char *MusicDriver_DMusic::Start(co
 
	_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL);
 
	if (_thread_event == NULL) return "Can't create thread shutdown event";
 

	
 
	if (!ThreadObject::New(&MidiThreadProc, this, &_dmusic_thread, "ottd:dmusic")) return "Can't create MIDI output thread";
 
	if (!StartNewThread(&_dmusic_thread, "ottd:dmusic", &MidiThreadProc)) return "Can't create MIDI output thread";
 

	
 
	return NULL;
 
}
 
@@ -1183,10 +1183,10 @@ MusicDriver_DMusic::~MusicDriver_DMusic(
 

	
 
void MusicDriver_DMusic::Stop()
 
{
 
	if (_dmusic_thread != NULL) {
 
	if (_dmusic_thread.joinable()) {
 
		_playback.shutdown = true;
 
		SetEvent(_thread_event);
 
		_dmusic_thread->Join();
 
		_dmusic_thread.join();
 
	}
 

	
 
	/* Unloaded any instruments we loaded. */
src/network/core/tcp.h
Show inline comments
 
@@ -63,7 +63,6 @@ public:
 
 */
 
class TCPConnecter {
 
private:
 
	class ThreadObject *thread; ///< Thread used to create the TCP connection
 
	bool connected;             ///< Whether we succeeded in making the connection
 
	bool aborted;               ///< Whether we bailed out (i.e. connection making failed)
 
	bool killed;                ///< Whether we got killed
 
@@ -71,7 +70,7 @@ private:
 

	
 
	void Connect();
 

	
 
	static void ThreadEntry(void *param);
 
	static void ThreadEntry(TCPConnecter *param);
 

	
 
protected:
 
	/** Address we're connecting to */
src/network/core/tcp_connect.cpp
Show inline comments
 
@@ -12,7 +12,7 @@
 
 */
 

	
 
#include "../../stdafx.h"
 
#include "../../thread/thread.h"
 
#include "../../thread.h"
 

	
 
#include "tcp.h"
 

	
 
@@ -33,7 +33,7 @@ TCPConnecter::TCPConnecter(const Network
 
	address(address)
 
{
 
	_tcp_connecters.push_back(this);
 
	if (!ThreadObject::New(TCPConnecter::ThreadEntry, this, &this->thread, "ottd:tcp")) {
 
	if (!StartNewThread(NULL, "ottd:tcp", &TCPConnecter::ThreadEntry, this)) {
 
		this->Connect();
 
	}
 
}
 
@@ -53,9 +53,9 @@ void TCPConnecter::Connect()
 
 * Entry point for the new threads.
 
 * @param param the TCPConnecter instance to call Connect on.
 
 */
 
/* static */ void TCPConnecter::ThreadEntry(void *param)
 
/* static */ void TCPConnecter::ThreadEntry(TCPConnecter *param)
 
{
 
	static_cast<TCPConnecter*>(param)->Connect();
 
	param->Connect();
 
}
 

	
 
/**
src/network/network_server.h
Show inline comments
 
@@ -14,7 +14,6 @@
 

	
 
#include "network_internal.h"
 
#include "core/tcp_listen.h"
 
#include "../thread/thread.h"
 

	
 
class ServerNetworkGameSocketHandler;
 
/** Make the code look slightly nicer/simpler. */
src/network/network_udp.cpp
Show inline comments
 
@@ -24,7 +24,7 @@
 
#include "network.h"
 
#include "../core/endian_func.hpp"
 
#include "../company_base.h"
 
#include "../thread/thread.h"
 
#include "../thread.h"
 
#include "../rev.h"
 
#include "../newgrf_text.h"
 
#include "../strings_func.h"
 
@@ -49,35 +49,19 @@ NetworkUDPSocketHandler *_udp_client_soc
 
NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket
 
NetworkUDPSocketHandler *_udp_master_socket = NULL; ///< udp master socket
 

	
 
/** Simpler wrapper struct for NetworkUDPQueryServerThread */
 
struct NetworkUDPQueryServerInfo : NetworkAddress {
 
	bool manually; ///< Did we connect manually or not?
 

	
 
	/**
 
	 * Create the structure.
 
	 * @param address The address of the server to query.
 
	 * @param manually Whether the address was entered manually.
 
	 */
 
	NetworkUDPQueryServerInfo(const NetworkAddress &address, bool manually) :
 
		NetworkAddress(address),
 
		manually(manually)
 
	{
 
	}
 
};
 

	
 
/**
 
 * Helper function doing the actual work for querying the server.
 
 * @param address The address of the server.
 
 * @param needs_mutex Whether we need to acquire locks when sending the packet or not.
 
 * @param manually Whether the address was entered manually.
 
 */
 
static void NetworkUDPQueryServer(NetworkAddress *address, bool needs_mutex, bool manually)
 
static void DoNetworkUDPQueryServer(NetworkAddress &address, bool needs_mutex, bool manually)
 
{
 
	/* Clear item in gamelist */
 
	NetworkGameList *item = CallocT<NetworkGameList>(1);
 
	address->GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
 
	strecpy(item->info.hostname, address->GetHostname(), lastof(item->info.hostname));
 
	item->address = *address;
 
	address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
 
	strecpy(item->info.hostname, address.GetHostname(), lastof(item->info.hostname));
 
	item->address = address;
 
	item->manually = manually;
 
	NetworkGameListAddItemDelayed(item);
 

	
 
@@ -85,19 +69,7 @@ static void NetworkUDPQueryServer(Networ
 
	if (needs_mutex) lock.lock();
 
	/* Init the packet */
 
	Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
 
	if (_udp_client_socket != NULL) _udp_client_socket->SendPacket(&p, address);
 
}
 

	
 
/**
 
 * Threaded part for resolving the IP of a server and querying it.
 
 * @param pntr the NetworkUDPQueryServerInfo.
 
 */
 
static void NetworkUDPQueryServerThread(void *pntr)
 
{
 
	NetworkUDPQueryServerInfo *info = (NetworkUDPQueryServerInfo*)pntr;
 
	NetworkUDPQueryServer(info, true, info->manually);
 

	
 
	delete info;
 
	if (_udp_client_socket != NULL) _udp_client_socket->SendPacket(&p, &address);
 
}
 

	
 
/**
 
@@ -107,9 +79,8 @@ static void NetworkUDPQueryServerThread(
 
 */
 
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
 
{
 
	NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually);
 
	if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info, NULL, "ottd:udp-query")) {
 
		NetworkUDPQueryServerThread(info);
 
	if (address.IsResolved() || !StartNewThread(NULL, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(address), true, std::move(manually))) {
 
		DoNetworkUDPQueryServer(address, true, manually);
 
	}
 
}
 

	
 
@@ -429,7 +400,7 @@ void ClientNetworkUDPSocketHandler::Rece
 
			/* Somehow we reached the end of the packet */
 
			if (this->HasClientQuit()) return;
 

	
 
			NetworkUDPQueryServer(&addr, false, false);
 
			DoNetworkUDPQueryServer(addr, false, false);
 
		}
 
	}
 
}
 
@@ -535,9 +506,8 @@ void NetworkUDPSearchGame()
 

	
 
/**
 
 * Thread entry point for de-advertising.
 
 * @param pntr unused.
 
 */
 
static void NetworkUDPRemoveAdvertiseThread(void *pntr)
 
static void NetworkUDPRemoveAdvertiseThread()
 
{
 
	DEBUG(net, 1, "[udp] removing advertise from master server");
 

	
 
@@ -563,16 +533,15 @@ void NetworkUDPRemoveAdvertise(bool bloc
 
	/* Check if we are advertising */
 
	if (!_networking || !_network_server || !_network_udp_server) return;
 

	
 
	if (blocking || !ThreadObject::New(NetworkUDPRemoveAdvertiseThread, NULL, NULL, "ottd:udp-advert")) {
 
		NetworkUDPRemoveAdvertiseThread(NULL);
 
	if (blocking || !StartNewThread(NULL, "ottd:udp-advert", &NetworkUDPRemoveAdvertiseThread)) {
 
		NetworkUDPRemoveAdvertiseThread();
 
	}
 
}
 

	
 
/**
 
 * Thread entry point for advertising.
 
 * @param pntr unused.
 
 */
 
static void NetworkUDPAdvertiseThread(void *pntr)
 
static void NetworkUDPAdvertiseThread()
 
{
 
	/* Find somewhere to send */
 
	NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT);
 
@@ -645,8 +614,8 @@ void NetworkUDPAdvertise()
 
	if (_next_advertisement < _last_advertisement) _next_advertisement = UINT32_MAX;
 
	if (_next_retry         < _last_advertisement) _next_retry         = UINT32_MAX;
 

	
 
	if (!ThreadObject::New(NetworkUDPAdvertiseThread, NULL, NULL, "ottd:udp-advert")) {
 
		NetworkUDPAdvertiseThread(NULL);
 
	if (!StartNewThread(NULL, "ottd:udp-advert", &NetworkUDPAdvertiseThread)) {
 
		NetworkUDPAdvertiseThread();
 
	}
 
}
 

	
src/newgrf_config.cpp
Show inline comments
 
@@ -21,7 +21,8 @@
 
#include "video/video_driver.hpp"
 
#include "strings_func.h"
 
#include "textfile_gui.h"
 
#include "thread/thread.h"
 
#include "thread.h"
 
#include "newgrf_config.h"
 

	
 
#include "fileio_func.h"
 
#include "fios.h"
 
@@ -724,7 +725,7 @@ static int CDECL GRFSorter(GRFConfig * c
 
 * Really perform the scan for all NewGRFs.
 
 * @param callback The callback to call after the scanning is complete.
 
 */
 
void DoScanNewGRFFiles(void *callback)
 
void DoScanNewGRFFiles(NewGRFScanCallback *callback)
 
{
 
	std::unique_lock<std::mutex> lock_work(_modal_progress_work_mutex);
 

	
 
@@ -767,7 +768,7 @@ void DoScanNewGRFFiles(void *callback)
 
	/* Yes... these are the NewGRF windows */
 
	InvalidateWindowClassesData(WC_SAVELOAD, 0, true);
 
	InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE, GOID_NEWGRF_RESCANNED, true);
 
	if (callback != NULL) ((NewGRFScanCallback*)callback)->OnNewGRFsScanned();
 
	if (callback != NULL) callback->OnNewGRFsScanned();
 

	
 
	DeleteWindowByClass(WC_MODAL_PROGRESS);
 
	SetModalProgress(false);
 
@@ -785,7 +786,7 @@ void ScanNewGRFFiles(NewGRFScanCallback 
 
	/* Only then can we really start, especially by marking the whole screen dirty. Get those other windows hidden!. */
 
	MarkWholeScreenDirty();
 

	
 
	if (!UseThreadedModelProgress() || !VideoDriver::GetInstance()->HasGUI() || !ThreadObject::New(&DoScanNewGRFFiles, callback, NULL, "ottd:newgrf-scan")) {
 
	if (!UseThreadedModelProgress() || !VideoDriver::GetInstance()->HasGUI() || !StartNewThread(NULL, "ottd:newgrf-scan", &DoScanNewGRFFiles, (NewGRFScanCallback *)callback)) { // Without the seemingly superfluous cast, strange compiler errors ensue.
 
		_modal_progress_work_mutex.unlock();
 
		_modal_progress_paint_mutex.unlock();
 
		DoScanNewGRFFiles(callback);
src/openttd.cpp
Show inline comments
 
@@ -857,6 +857,7 @@ int openttd_main(int argc, char *argv[])
 
	VideoDriver::GetInstance()->MainLoop();
 

	
 
	WaitTillSaved();
 
	WaitTillGeneratedWorld(); // Make sure any generate world threads have been joined.
 

	
 
	/* only save config if we have to */
 
	if (save_config) {
src/os/os2/os2.cpp
Show inline comments
 
@@ -18,6 +18,7 @@
 
#include "../../core/random_func.hpp"
 
#include "../../string_func.h"
 
#include "../../textbuf_gui.h"
 
#include "../../thread.h"
 

	
 
#include "table/strings.h"
 

	
 
@@ -226,3 +227,7 @@ void OSOpenBrowser(const char *url)
 
	// stub only
 
	DEBUG(misc, 0, "Failed to open url: %s", url);
 
}
 

	
 
void SetCurrentThreadName(const char *)
 
{
 
}
src/os/unix/unix.cpp
Show inline comments
 
@@ -17,6 +17,7 @@
 
#include "../../debug.h"
 
#include "../../string_func.h"
 
#include "../../fios.h"
 
#include "../../thread.h"
 

	
 

	
 
#include <dirent.h>
 
@@ -43,11 +44,17 @@
 
#include <sys/sysctl.h>
 
#endif
 

	
 
#ifndef NO_THREADS
 
#include <pthread.h>
 
#endif
 

	
 
#if defined(__APPLE__)
 
	#if defined(WITH_SDL)
 
#	if defined(WITH_SDL)
 
		/* the mac implementation needs this file included in the same file as main() */
 
		#include <SDL.h>
 
	#endif
 
#		include <SDL.h>
 
#	endif
 

	
 
#	include "../macosx/macos.h"
 
#endif
 

	
 
#include "../../safeguards.h"
 
@@ -317,4 +324,15 @@ void OSOpenBrowser(const char *url)
 
	DEBUG(misc, 0, "Failed to open url: %s", url);
 
	exit(0);
 
}
 
#endif
 
#endif /* __APPLE__ */
 

	
 
void SetCurrentThreadName(const char *threadName) {
 
#if !defined(NO_THREADS) && defined(__GLIBC__)
 
#if __GLIBC_PREREQ(2, 12)
 
	if (threadName) pthread_setname_np(pthread_self(), threadName);
 
#endif /* __GLIBC_PREREQ(2, 12) */
 
#endif /* !defined(NO_THREADS) && defined(__GLIBC__) */
 
#if defined(__APPLE__)
 
	MacOSSetThreadName(threadName);
 
#endif /* defined(__APPLE__) */
 
}
src/os/windows/win32.cpp
Show inline comments
 
@@ -30,6 +30,7 @@
 
#include <errno.h>
 
#include <sys/stat.h>
 
#include "../../language.h"
 
#include "../../thread.h"
 

	
 
#include "../../safeguards.h"
 

	
 
@@ -816,12 +817,12 @@ PACK_N(struct THREADNAME_INFO {
 
/**
 
 * Signal thread name to any attached debuggers.
 
 */
 
void SetWin32ThreadName(DWORD dwThreadID, const char* threadName)
 
void SetCurrentThreadName(const char *threadName)
 
{
 
	THREADNAME_INFO info;
 
	info.dwType = 0x1000;
 
	info.szName = threadName;
 
	info.dwThreadID = dwThreadID;
 
	info.dwThreadID = -1;
 
	info.dwFlags = 0;
 

	
 
#pragma warning(push)
 
@@ -832,4 +833,6 @@ void SetWin32ThreadName(DWORD dwThreadID
 
	}
 
#pragma warning(pop)
 
}
 
#else
 
void SetCurrentThreadName(const char *) {}
 
#endif
src/os/windows/win32.h
Show inline comments
 
@@ -39,12 +39,6 @@ HRESULT OTTDSHGetFolderPath(HWND, int, H
 
#define SHGFP_TYPE_CURRENT 0
 
#endif /* __MINGW32__ */
 

	
 
#ifdef _MSC_VER
 
void SetWin32ThreadName(DWORD dwThreadID, const char* threadName);
 
#else
 
static inline void SetWin32ThreadName(DWORD dwThreadID, const char* threadName) {}
 
#endif
 

	
 
void Win32SetCurrentLocaleName(const char *iso_code);
 
int OTTDStringCompare(const char *s1, const char *s2);
 

	
src/saveload/saveload.cpp
Show inline comments
 
@@ -26,7 +26,7 @@
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "../station_base.h"
 
#include "../thread/thread.h"
 
#include "../thread.h"
 
#include "../town.h"
 
#include "../network/network.h"
 
#include "../window_func.h"
 
@@ -372,7 +372,7 @@ void NORETURN SlErrorCorruptFmt(const ch
 

	
 
typedef void (*AsyncSaveFinishProc)();                ///< Callback for when the savegame loading is finished.
 
static AsyncSaveFinishProc _async_save_finish = NULL; ///< Callback to call when the savegame loading is finished.
 
static ThreadObject *_save_thread;                    ///< The thread we're using to compress and write a savegame
 
static std::thread _save_thread;                      ///< The thread we're using to compress and write a savegame
 

	
 
/**
 
 * Called by save thread to tell we finished saving.
 
@@ -397,10 +397,8 @@ void ProcessAsyncSaveFinish()
 

	
 
	_async_save_finish = NULL;
 

	
 
	if (_save_thread != NULL) {
 
		_save_thread->Join();
 
		delete _save_thread;
 
		_save_thread = NULL;
 
	if (_save_thread.joinable()) {
 
		_save_thread.join();
 
	}
 
}
 

	
 
@@ -2486,19 +2484,11 @@ static SaveOrLoadResult SaveFileToDisk(b
 
	}
 
}
 

	
 
/** Thread run function for saving the file to disk. */
 
static void SaveFileToDiskThread(void *arg)
 
{
 
	SaveFileToDisk(true);
 
}
 

	
 
void WaitTillSaved()
 
{
 
	if (_save_thread == NULL) return;
 

	
 
	_save_thread->Join();
 
	delete _save_thread;
 
	_save_thread = NULL;
 
	if (!_save_thread.joinable()) return;
 

	
 
	_save_thread.join();
 

	
 
	/* Make sure every other state is handled properly as well. */
 
	ProcessAsyncSaveFinish();
 
@@ -2525,7 +2515,8 @@ static SaveOrLoadResult DoSave(SaveFilte
 
	SlSaveChunks();
 

	
 
	SaveFileStart();
 
	if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread, "ottd:savegame")) {
 

	
 
	if (!threaded || !StartNewThread(&_save_thread, "ottd:savegame", &SaveFileToDisk, true)) {
 
		if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
 

	
 
		SaveOrLoadResult result = SaveFileToDisk(false);
src/sound/win32_s.cpp
Show inline comments
 
@@ -20,6 +20,7 @@
 
#include <windows.h>
 
#include <mmsystem.h>
 
#include "../os/windows/win32.h"
 
#include "../thread.h"
 

	
 
#include "../safeguards.h"
 

	
 
@@ -42,7 +43,7 @@ static void PrepareHeader(WAVEHDR *hdr)
 

	
 
static DWORD WINAPI SoundThread(LPVOID arg)
 
{
 
	SetWin32ThreadName(-1, "ottd:win-sound");
 
	SetCurrentThreadName("ottd:win-sound");
 

	
 
	do {
 
		for (WAVEHDR *hdr = _wave_hdr; hdr != endof(_wave_hdr); hdr++) {
src/thread.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file thread.h Base of all threads. */
 

	
 
#ifndef THREAD_H
 
#define THREAD_H
 

	
 
#include "debug.h"
 
#include <system_error>
 
#include <thread>
 

	
 
/** Signal used for signalling we knowingly want to end the thread. */
 
class OTTDThreadExitSignal { };
 

	
 

	
 
/**
 
 * Get number of processor cores in the system, including HyperThreading or similar.
 
 * @return Total number of processor cores.
 
 */
 
uint GetCPUCoreCount();
 

	
 
/**
 
 * Name the thread this function is called on for the debugger.
 
 * @param name Name to set for the thread..
 
 */
 
void SetCurrentThreadName(const char *name);
 

	
 

	
 
/**
 
 * Start a new thread.
 
 * @tparam TFn Type of the function to call on the thread.
 
 * @tparam TArgs Type of the parameters of the thread function.
 
 * @param thr Pointer to a thread object; may be \c NULL if a detached thread is wanted.
 
 * @param name Name of the thread.
 
 * @param _Fx Function to call on the thread.
 
 * @param _Ax Arguments for the thread function.
 
 * @return True if the thread was successfully started, false otherwise.
 
 */
 
template<class TFn, class... TArgs>
 
inline bool StartNewThread(std::thread *thr, const char *name, TFn&& _Fx, TArgs&&... _Ax)
 
{
 
#ifndef NO_THREADS
 
	try {
 
		std::thread t([] (const char *name, TFn&& F, TArgs&&... A) {
 
				SetCurrentThreadName(name);
 
				try {
 
					/* Call user function with the given arguments. */
 
					F(A...);
 
				} catch (OTTDThreadExitSignal&) {
 
				} catch (...) {
 
					NOT_REACHED();
 
				}
 
			}, name, std::forward<TFn>(_Fx), std::forward<TArgs>(_Ax)...);
 

	
 
		if (thr != NULL) {
 
			*thr = std::move(t);
 
		} else {
 
			t.detach();
 
		}
 

	
 
		return true;
 
	} catch (const std::system_error& e) {
 
		/* Something went wrong, the system we are running on might not support threads. */
 
		DEBUG(misc, 1, "Can't create thread '%s': %s", name, e.what());
 
	}
 
#endif
 

	
 
	return false;
 
}
 

	
 
#endif /* THREAD_H */
src/thread/thread.h
Show inline comments
 
deleted file
src/thread/thread_none.cpp
Show inline comments
 
deleted file
src/thread/thread_os2.cpp
Show inline comments
 
deleted file
src/thread/thread_pthread.cpp
Show inline comments
 
deleted file
src/thread/thread_win32.cpp
Show inline comments
 
deleted file
src/video/dedicated_v.cpp
Show inline comments
 
@@ -73,6 +73,7 @@ static void DedicatedSignalHandler(int s
 
# include <time.h>
 
# include <tchar.h>
 
# include "../os/windows/win32.h"
 
# include "../thread.h"
 
static HANDLE _hInputReady, _hWaitForInputHandling;
 
static HANDLE _hThread; // Thread to close
 
static char _win_console_thread_buffer[200];
 
@@ -80,7 +81,7 @@ static char _win_console_thread_buffer[2
 
/* Windows Console thread. Just loop and signal when input has been received */
 
static void WINAPI CheckForConsoleInput()
 
{
 
	SetWin32ThreadName(-1, "ottd:win-console");
 
	SetCurrentThreadName("ottd:win-console");
 

	
 
	DWORD nb;
 
	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
src/video/sdl_v.cpp
Show inline comments
 
@@ -17,7 +17,7 @@
 
#include "../rev.h"
 
#include "../blitter/factory.hpp"
 
#include "../network/network.h"
 
#include "../thread/thread.h"
 
#include "../thread.h"
 
#include "../progress.h"
 
#include "../core/random_func.hpp"
 
#include "../core/math_func.hpp"
 
@@ -38,8 +38,6 @@ static bool _all_modes;
 

	
 
/** Whether the drawing is/may be done in a separate thread. */
 
static bool _draw_threaded;
 
/** Thread used to 'draw' to the screen, i.e. push data to the screen. */
 
static ThreadObject *_draw_thread = NULL;
 
/** Mutex to keep the access to the shared memory controlled. */
 
static std::recursive_mutex *_draw_mutex = NULL;
 
/** Signal to draw the next frame. */
 
@@ -173,7 +171,7 @@ static void DrawSurfaceToScreen()
 
	}
 
}
 

	
 
static void DrawSurfaceToScreenThread(void *)
 
static void DrawSurfaceToScreenThread()
 
{
 
	/* First tell the main thread we're started */
 
	std::unique_lock<std::recursive_mutex> lock(*_draw_mutex);
 
@@ -188,8 +186,6 @@ static void DrawSurfaceToScreenThread(vo
 
		DrawSurfaceToScreen();
 
		_draw_signal->wait(lock);
 
	}
 

	
 
	_draw_thread->Exit();
 
}
 

	
 
static const Dimension _default_resolutions[] = {
 
@@ -671,6 +667,7 @@ void VideoDriver_SDL::MainLoop()
 

	
 
	CheckPaletteAnim();
 

	
 
	std::thread draw_thread;
 
	std::unique_lock<std::recursive_mutex> draw_lock;
 
	if (_draw_threaded) {
 
		/* Initialise the mutex first, because that's the thing we *need*
 
@@ -683,7 +680,7 @@ void VideoDriver_SDL::MainLoop()
 
			_draw_signal = new std::condition_variable_any();
 
			_draw_continue = true;
 

	
 
			_draw_threaded = ThreadObject::New(&DrawSurfaceToScreenThread, NULL, &_draw_thread, "ottd:draw-sdl");
 
			_draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &DrawSurfaceToScreenThread);
 

	
 
			/* Free the mutex if we won't be able to use it. */
 
			if (!_draw_threaded) {
 
@@ -795,15 +792,13 @@ void VideoDriver_SDL::MainLoop()
 
		_draw_signal->notify_one();
 
		if (draw_lock.owns_lock()) draw_lock.unlock();
 
		draw_lock.release();
 
		_draw_thread->Join();
 
		draw_thread.join();
 

	
 
		delete _draw_mutex;
 
		delete _draw_signal;
 
		delete _draw_thread;
 

	
 
		_draw_mutex = NULL;
 
		_draw_signal = NULL;
 
		_draw_thread = NULL;
 
	}
 
}
 

	
src/video/win32_v.cpp
Show inline comments
 
@@ -19,7 +19,7 @@
 
#include "../core/math_func.hpp"
 
#include "../core/random_func.hpp"
 
#include "../texteff.hpp"
 
#include "../thread/thread.h"
 
#include "../thread.h"
 
#include "../progress.h"
 
#include "../window_gui.h"
 
#include "../window_func.h"
 
@@ -67,8 +67,6 @@ DWORD _imm_props;
 

	
 
/** Whether the drawing is/may be done in a separate thread. */
 
static bool _draw_threaded;
 
/** Thread used to 'draw' to the screen, i.e. push data to the screen. */
 
static ThreadObject *_draw_thread = NULL;
 
/** Mutex to keep the access to the shared memory controlled. */
 
static std::recursive_mutex *_draw_mutex = NULL;
 
/** Signal to draw the next frame. */
 
@@ -395,7 +393,7 @@ static void PaintWindow(HDC dc)
 
	DeleteDC(dc2);
 
}
 

	
 
static void PaintWindowThread(void *)
 
static void PaintWindowThread()
 
{
 
	/* First tell the main thread we're started */
 
	std::unique_lock<std::recursive_mutex> lock(*_draw_mutex);
 
@@ -426,8 +424,6 @@ static void PaintWindowThread(void *)
 

	
 
		_draw_signal->wait(*_draw_mutex);
 
	}
 

	
 
	_draw_thread->Exit();
 
}
 

	
 
/** Forward key presses to the window system. */
 
@@ -1190,6 +1186,7 @@ void VideoDriver_Win32::MainLoop()
 
	uint32 last_cur_ticks = cur_ticks;
 
	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
 

	
 
	std::thread draw_thread;
 
	std::unique_lock<std::recursive_mutex> draw_lock;
 

	
 
	if (_draw_threaded) {
 
@@ -1206,7 +1203,7 @@ void VideoDriver_Win32::MainLoop()
 
			draw_lock = std::unique_lock<std::recursive_mutex>(*_draw_mutex);
 

	
 
			_draw_continue = true;
 
			_draw_threaded = ThreadObject::New(&PaintWindowThread, NULL, &_draw_thread, "ottd:draw-win32");
 
			_draw_threaded = StartNewThread(&draw_thread, "ottd:draw-win32", &PaintWindowThread);
 

	
 
			/* Free the mutex if we won't be able to use it. */
 
			if (!_draw_threaded) {
 
@@ -1308,11 +1305,10 @@ void VideoDriver_Win32::MainLoop()
 
		_draw_signal->notify_all();
 
		if (draw_lock.owns_lock()) draw_lock.unlock();
 
		draw_lock.release();
 
		_draw_thread->Join();
 
		draw_thread.join();
 

	
 
		delete _draw_mutex;
 
		delete _draw_signal;
 
		delete _draw_thread;
 

	
 
		_draw_mutex = NULL;
 
	}
0 comments (0 inline, 0 general)