Split out TLS code into separate modules.

This allows the TLS code to be re-used by partial ports like EGL.
This commit is contained in:
Camilla Berglund 2014-03-30 14:37:20 +02:00
parent 2889f484f4
commit 78efc18079
16 changed files with 278 additions and 88 deletions

View File

@ -12,20 +12,20 @@ set(common_SOURCES clipboard.c context.c gamma.c init.c input.c joystick.c
monitor.c time.c window.c)
if (_GLFW_COCOA)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h posix_tls.h)
set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_gamma.c
cocoa_init.m cocoa_joystick.m cocoa_monitor.m cocoa_time.c
cocoa_window.m)
cocoa_window.m posix_tls.c)
elseif (_GLFW_WIN32)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h)
set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_gamma.c
win32_init.c win32_joystick.c win32_monitor.c win32_time.c
win32_window.c)
win32_tls.c win32_window.c)
elseif (_GLFW_X11)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h posix_tls.h)
set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_gamma.c x11_init.c
x11_joystick.c x11_monitor.c x11_time.c x11_window.c
x11_unicode.c)
x11_unicode.c posix_tls.c)
endif()
if (_GLFW_EGL)

View File

@ -37,6 +37,8 @@
typedef void* id;
#endif
#include "posix_tls.h"
#if defined(_GLFW_NSGL)
#include "nsgl_platform.h"
#else

View File

@ -32,22 +32,6 @@
#include <assert.h>
// Thread local storage attribute macro
//
#if defined(_MSC_VER)
#define _GLFW_TLS __declspec(thread)
#elif defined(__GNUC__)
#define _GLFW_TLS __thread
#else
#define _GLFW_TLS
#endif
// The per-thread current context/window pointer
//
static _GLFW_TLS _GLFWwindow* _glfwCurrentWindow = NULL;
// Return a description of the specified EGL error
//
static const char* getErrorString(EGLint error)
@ -207,6 +191,9 @@ static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
//
int _glfwInitContextAPI(void)
{
if (!_glfwInitTLS())
return GL_FALSE;
_glfw.egl.display = eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
@ -237,6 +224,8 @@ int _glfwInitContextAPI(void)
void _glfwTerminateContextAPI(void)
{
eglTerminate(_glfw.egl.display);
_glfwTerminateTLS();
}
#define setEGLattrib(attribName, attribValue) \
@ -482,12 +471,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
_glfwCurrentWindow = window;
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return _glfwCurrentWindow;
_glfwSetCurrentContext(window);
}
void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -165,6 +165,9 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
//
int _glfwInitContextAPI(void)
{
if (!_glfwInitTLS())
return GL_FALSE;
#ifdef _GLFW_DLOPEN_LIBGL
_glfw.glx.libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (!_glfw.glx.libGL)
@ -174,13 +177,6 @@ int _glfwInitContextAPI(void)
}
#endif
if (pthread_key_create(&_glfw.glx.current, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to create context TLS");
return GL_FALSE;
}
if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase,
&_glfw.glx.eventBase))
@ -272,7 +268,7 @@ void _glfwTerminateContextAPI(void)
}
#endif
pthread_key_delete(_glfw.glx.current);
_glfwTerminateTLS();
}
#define setGLXattrib(attribName, attribValue) \
@ -478,12 +474,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
else
glXMakeCurrent(_glfw.x11.display, None, NULL);
pthread_setspecific(_glfw.glx.current, window);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return (_GLFWwindow*) pthread_getspecific(_glfw.glx.current);
_glfwSetCurrentContext(window);
}
void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -41,8 +41,6 @@
#include <dlfcn.h>
#endif
#include <pthread.h>
// We support four different ways for getting addresses for GL/GLX
// extension functions: glXGetProcAddress, glXGetProcAddressARB,
// glXGetProcAddressEXT, and dlsym
@ -93,9 +91,6 @@ typedef struct _GLFWlibraryGLX
int eventBase;
int errorBase;
// TLS key for per-thread current context/window
pthread_key_t current;
// GLX extensions
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;

View File

@ -348,6 +348,8 @@ struct _GLFWlibrary
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
// This is defined in the context API's platform.h
_GLFW_PLATFORM_LIBRARY_OPENGL_STATE;
// This is defined in the platform's tls.h
_GLFW_PLATFORM_TLS_STATE;
};

View File

@ -26,8 +26,6 @@
#include "internal.h"
#include <pthread.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
@ -37,12 +35,8 @@
//
int _glfwInitContextAPI(void)
{
if (pthread_key_create(&_glfw.nsgl.current, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"NSGL: Failed to create context TLS");
if (!_glfwInitTLS())
return GL_FALSE;
}
_glfw.nsgl.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
@ -60,7 +54,7 @@ int _glfwInitContextAPI(void)
//
void _glfwTerminateContextAPI(void)
{
pthread_key_delete(_glfw.nsgl.current);
_glfwTerminateTLS();
}
// Create the OpenGL context
@ -235,12 +229,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
else
[NSOpenGLContext clearCurrentContext];
pthread_setspecific(_glfw.nsgl.current, window);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return (_GLFWwindow*) pthread_getspecific(_glfw.nsgl.current);
_glfwSetCurrentContext(window);
}
void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -27,7 +27,6 @@
#ifndef _nsgl_platform_h_
#define _nsgl_platform_h_
#define _GLFW_PLATFORM_FBCONFIG
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryNSGL nsgl
@ -55,9 +54,6 @@ typedef struct _GLFWlibraryNSGL
// dlopen handle for dynamically loading OpenGL extension entry points
void* framework;
// TLS key for per-thread current context/window
pthread_key_t current;
} _GLFWlibraryNSGL;

66
src/posix_tls.c Normal file
View File

@ -0,0 +1,66 @@
//========================================================================
// GLFW 3.1 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
int _glfwInitTLS(void)
{
if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"POSIX: Failed to create context TLS");
return GL_FALSE;
}
return GL_TRUE;
}
void _glfwTerminateTLS(void)
{
pthread_key_delete(_glfw.posix_tls.context);
}
void _glfwSetCurrentContext(_GLFWwindow* context)
{
pthread_setspecific(_glfw.posix_tls.context, context);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return pthread_getspecific(_glfw.posix_tls.context);
}

55
src/posix_tls.h Normal file
View File

@ -0,0 +1,55 @@
//========================================================================
// GLFW 3.1 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _posix_tls_h_
#define _posix_tls_h_
#include <pthread.h>
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix_tls
//========================================================================
// GLFW platform specific types
//========================================================================
typedef struct _GLFWtlsPOSIX
{
pthread_key_t context;
} _GLFWtlsPOSIX;
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
int _glfwInitTLS(void);
void _glfwTerminateTLS(void);
void _glfwSetCurrentContext(_GLFWwindow* context);
#endif // _posix_tls_h_

View File

@ -306,6 +306,9 @@ static GLboolean choosePixelFormat(_GLFWwindow* window,
//
int _glfwInitContextAPI(void)
{
if (!_glfwInitTLS())
return GL_FALSE;
_glfw.wgl.opengl32.instance = LoadLibraryW(L"opengl32.dll");
if (!_glfw.wgl.opengl32.instance)
{
@ -313,16 +316,6 @@ int _glfwInitContextAPI(void)
return GL_FALSE;
}
_glfw.wgl.current = TlsAlloc();
if (_glfw.wgl.current == TLS_OUT_OF_INDEXES)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to allocate TLS index");
return GL_FALSE;
}
_glfw.wgl.hasTLS = GL_TRUE;
return GL_TRUE;
}
@ -330,11 +323,10 @@ int _glfwInitContextAPI(void)
//
void _glfwTerminateContextAPI(void)
{
if (_glfw.wgl.hasTLS)
TlsFree(_glfw.wgl.current);
if (_glfw.wgl.opengl32.instance)
FreeLibrary(_glfw.wgl.opengl32.instance);
_glfwTerminateTLS();
}
#define setWGLattrib(attribName, attribValue) \
@ -588,12 +580,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
else
wglMakeCurrent(NULL, NULL);
TlsSetValue(_glfw.wgl.current, window);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return TlsGetValue(_glfw.wgl.current);
_glfwSetCurrentContext(window);
}
void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -33,7 +33,6 @@
// extensions and not all operating systems come with an up-to-date version
#include "../deps/GL/wglext.h"
#define _GLFW_PLATFORM_FBCONFIG int wgl
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryWGL wgl
@ -74,9 +73,6 @@ typedef struct _GLFWcontextWGL
//------------------------------------------------------------------------
typedef struct _GLFWlibraryWGL
{
GLboolean hasTLS;
DWORD current;
// opengl32.dll
struct {
HINSTANCE instance;

View File

@ -151,6 +151,8 @@ typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*);
#define _GLFW_RECREATION_IMPOSSIBLE 2
#include "win32_tls.h"
#if defined(_GLFW_WGL)
#include "wgl_platform.h"
#elif defined(_GLFW_EGL)

69
src/win32_tls.c Normal file
View File

@ -0,0 +1,69 @@
//========================================================================
// GLFW 3.1 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
int _glfwInitTLS(void)
{
_glfw.win32_tls.context = TlsAlloc();
if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to allocate TLS index");
return GL_FALSE;
}
_glfw.win32_tls.allocated = GL_TRUE;
return GL_TRUE;
}
void _glfwTerminateTLS(void)
{
if (_glfw.win32_tls.allocated)
TlsFree(_glfw.win32_tls.context);
}
void _glfwSetCurrentContext(_GLFWwindow* context)
{
TlsSetValue(_glfw.win32_tls.context, context);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return TlsGetValue(_glfw.win32_tls.context);
}

54
src/win32_tls.h Normal file
View File

@ -0,0 +1,54 @@
//========================================================================
// GLFW 3.1 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _win32_tls_h_
#define _win32_tls_h_
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32_tls
//========================================================================
// GLFW platform specific types
//========================================================================
typedef struct _GLFWtlsWin32
{
GLboolean allocated;
DWORD context;
} _GLFWtlsWin32;
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
int _glfwInitTLS(void);
void _glfwTerminateTLS(void);
void _glfwSetCurrentContext(_GLFWwindow* context);
#endif // _win32_tls_h_

View File

@ -48,6 +48,8 @@
// The Xkb extension provides improved keyboard support
#include <X11/XKBlib.h>
#include "posix_tls.h"
#if defined(_GLFW_GLX)
#define _GLFW_X11_CONTEXT_VISUAL window->glx.visual
#include "glx_platform.h"