blob: 4f14d05e982507ac2d162cd2adbd91428b355fd5 [file] [log] [blame]
// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef STARBOARD_SHARED_WIN32_THREAD_PRIVATE_H_
#define STARBOARD_SHARED_WIN32_THREAD_PRIVATE_H_
#include <windows.h>
#include <map>
#include <string>
#include "starboard/common/condition_variable.h"
#include "starboard/common/mutex.h"
#include "starboard/common/once.h"
#include "starboard/shared/internal_only.h"
#include "starboard/thread.h"
#define kSbThreadLocalKeyInvalid (SbThreadLocalKey) NULL
typedef void (*SbThreadLocalDestructor)(void* value);
struct SbThreadLocalKeyPrivate {
DWORD tls_index;
SbThreadLocalDestructor destructor;
};
typedef SbThreadLocalKeyPrivate* SbThreadLocalKey;
static inline bool SbThreadIsValidLocalKey(SbThreadLocalKey key) {
return key != kSbThreadLocalKeyInvalid;
}
namespace starboard {
namespace shared {
namespace win32 {
class ThreadSubsystemSingleton;
SbThreadLocalKey ThreadCreateLocalKey(SbThreadLocalDestructor destructor);
void ThreadDestroyLocalKey(SbThreadLocalKey key);
void* ThreadGetLocalValue(SbThreadLocalKey key);
bool ThreadSetLocalValue(SbThreadLocalKey key, void* value);
// Creates a SbThreadLocalKey given a ThreadSubsystemSingleton. Used
// to create the first SbThreadLocalKey.
SbThreadLocalKey SbThreadCreateLocalKeyInternal(
SbThreadLocalDestructor destructor,
ThreadSubsystemSingleton* singleton);
// Singleton state for the thread subsystem.
class ThreadSubsystemSingleton {
public:
ThreadSubsystemSingleton()
: mutex_(PTHREAD_MUTEX_INITIALIZER),
thread_private_key_(SbThreadCreateLocalKeyInternal(NULL, this)) {}
// This mutex protects all class members
pthread_mutex_t mutex_;
// Allocated thread_local_keys. Note that std::map is used
// so that elements can be deleted without triggering an allocation.
std::map<DWORD, SbThreadLocalKeyPrivate*> thread_local_keys_;
// Thread-local key for the thread's SbThreadPrivate
SbThreadLocalKey thread_private_key_;
};
// Obtains the ThreadsSubsystemSingleton();
ThreadSubsystemSingleton* GetThreadSubsystemSingleton();
// Registers the main thread. setting it's SbThreadPrivate*
void RegisterMainThread();
// Private thread state, stored in thread local storage and
// cleaned up when thread exits.
class SbThreadPrivate {
public:
SbThreadPrivate()
: mutex_(PTHREAD_MUTEX_INITIALIZER),
condition_(PTHREAD_COND_INITIALIZER),
handle_(NULL),
result_(NULL),
wait_for_join_(false),
result_is_valid_(false) {}
~SbThreadPrivate() {
if (handle_) {
CloseHandle(handle_);
}
pthread_mutex_destroy(&mutex_);
pthread_cond_destroy(&condition_);
}
// This mutex protects all class members
pthread_mutex_t mutex_;
pthread_cond_t condition_;
std::string name_;
HANDLE handle_;
// The result of the thread. The return value of SbThreadEntryPoint
// to return to SbThreadJoin.
void* result_;
// True if a thread must wait to be joined before completely exiting.
// Changes to this must signal |condition_|.
bool wait_for_join_;
// True if |result_| is valid (the thread has completed and is waiting
// to exit). Changes to this must signal |condition_|.
bool result_is_valid_;
};
// Obtains the current thread's SbThreadPrivate* from thread-local storage.
SbThreadPrivate* GetCurrentSbThreadPrivate();
typedef void* (*SbThreadEntryPoint)(void* context);
class ThreadCreateInfo {
public:
SbThreadPrivate thread_private_;
SbThreadEntryPoint entry_point_;
void* user_context_;
std::string name_;
};
} // namespace win32
} // namespace shared
} // namespace starboard
#endif // STARBOARD_SHARED_WIN32_THREAD_PRIVATE_H_