forked from enlightenment/efl
Separate eina_thred.c into eina_thread_posix.c and eina_thread_win32.c; Changed the meson.build to call theses files according to SO.
This commit is contained in:
parent
ed0287d23b
commit
425a9a5fbd
|
@ -33,7 +33,14 @@
|
|||
|
||||
#include "eina_debug_private.h"
|
||||
|
||||
#include <pthread.h>
|
||||
/*
|
||||
#ifndef _WIN32
|
||||
|
||||
# include "eina_thread_posix.h"
|
||||
#else
|
||||
# include "eina_thread_win32.h"
|
||||
#endif
|
||||
*/
|
||||
#include <errno.h>
|
||||
#ifndef _WIN32
|
||||
# include <signal.h>
|
||||
|
@ -47,113 +54,7 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
static inline void *
|
||||
_eina_thread_join(Eina_Thread t)
|
||||
{
|
||||
void *ret = NULL;
|
||||
int err = pthread_join((pthread_t)t, &ret);
|
||||
|
||||
if (err == 0) return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_eina_thread_create(Eina_Thread *t, int affinity, void *(*func)(void *data), void *data)
|
||||
{
|
||||
int err;
|
||||
pthread_attr_t attr;
|
||||
#ifndef _WIN32
|
||||
sigset_t oldset, newset;
|
||||
#endif
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
if (affinity >= 0)
|
||||
{
|
||||
#ifdef EINA_HAVE_PTHREAD_AFFINITY
|
||||
cpu_set_t cpu;
|
||||
|
||||
CPU_ZERO(&cpu);
|
||||
CPU_SET(affinity, &cpu);
|
||||
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* setup initial locks */
|
||||
#ifndef _WIN32
|
||||
sigemptyset(&newset);
|
||||
sigaddset(&newset, SIGPIPE);
|
||||
sigaddset(&newset, SIGALRM);
|
||||
sigaddset(&newset, SIGCHLD);
|
||||
sigaddset(&newset, SIGUSR1);
|
||||
sigaddset(&newset, SIGUSR2);
|
||||
sigaddset(&newset, SIGHUP);
|
||||
sigaddset(&newset, SIGQUIT);
|
||||
sigaddset(&newset, SIGINT);
|
||||
sigaddset(&newset, SIGTERM);
|
||||
# ifdef SIGPWR
|
||||
sigaddset(&newset, SIGPWR);
|
||||
# endif
|
||||
pthread_sigmask(SIG_BLOCK, &newset, &oldset);
|
||||
#endif
|
||||
err = pthread_create((pthread_t *)t, &attr, func, data);
|
||||
#ifndef _WIN32
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
#endif
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
if (err == 0) return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_eina_thread_equal(Eina_Thread t1, Eina_Thread t2)
|
||||
{
|
||||
return pthread_equal((pthread_t)t1, (pthread_t)t2);
|
||||
}
|
||||
|
||||
static inline Eina_Thread
|
||||
_eina_thread_self(void)
|
||||
{
|
||||
return (Eina_Thread)pthread_self();
|
||||
}
|
||||
|
||||
|
||||
typedef struct _Eina_Thread_Call Eina_Thread_Call;
|
||||
struct _Eina_Thread_Call
|
||||
{
|
||||
Eina_Thread_Cb func;
|
||||
const void *data;
|
||||
|
||||
Eina_Thread_Priority prio;
|
||||
int affinity;
|
||||
};
|
||||
|
||||
static void *
|
||||
_eina_internal_call(void *context)
|
||||
{
|
||||
Eina_Thread_Call *c = context;
|
||||
void *r;
|
||||
pthread_t self;
|
||||
|
||||
// Default this thread to not cancellable as per Eina documentation
|
||||
eina_thread_cancellable_set(EINA_FALSE, NULL);
|
||||
|
||||
EINA_THREAD_CLEANUP_PUSH(free, c);
|
||||
|
||||
if (c->prio == EINA_THREAD_BACKGROUND ||
|
||||
c->prio == EINA_THREAD_IDLE)
|
||||
eina_sched_prio_drop();
|
||||
|
||||
self = pthread_self();
|
||||
_eina_debug_thread_add(&self);
|
||||
EINA_THREAD_CLEANUP_PUSH(_eina_debug_thread_del, &self);
|
||||
r = c->func((void*) c->data, eina_thread_self());
|
||||
EINA_THREAD_CLEANUP_POP(EINA_TRUE);
|
||||
EINA_THREAD_CLEANUP_POP(EINA_TRUE);
|
||||
|
||||
return r;
|
||||
}
|
||||
static void *_eina_internal_call(void *context);
|
||||
|
||||
EAPI Eina_Thread
|
||||
eina_thread_self(void)
|
||||
|
@ -212,8 +113,9 @@ eina_thread_name_set(Eina_Thread t, const char *name)
|
|||
}
|
||||
else buf[0] = 0;
|
||||
#ifndef __linux__
|
||||
pthread_set_name_np((pthread_t)t, buf);
|
||||
return EINA_TRUE;
|
||||
//pthread_set_name_np((pthread_t)t, buf);
|
||||
//return EINA_TRUE;
|
||||
return _eina_thread_set_name_win32(t, buf);
|
||||
#else
|
||||
if (pthread_setname_np((pthread_t)t, buf) == 0) return EINA_TRUE;
|
||||
#endif
|
||||
|
@ -228,7 +130,11 @@ EAPI Eina_Bool
|
|||
eina_thread_cancel(Eina_Thread t)
|
||||
{
|
||||
if (!t) return EINA_FALSE;
|
||||
#ifndef _WIN32
|
||||
return pthread_cancel((pthread_t)t) == 0;
|
||||
#else
|
||||
return _eina_thread_cancel(t);
|
||||
#endif
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
@ -237,21 +143,32 @@ eina_thread_cancellable_set(Eina_Bool cancellable, Eina_Bool *was_cancellable)
|
|||
int state = cancellable ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE;
|
||||
int old = 0;
|
||||
int r;
|
||||
|
||||
#ifndef _WIN32
|
||||
/* enforce deferred in case users changed to asynchronous themselves */
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old);
|
||||
|
||||
r = pthread_setcancelstate(state, &old);
|
||||
if (was_cancellable && r == 0)
|
||||
*was_cancellable = (old == PTHREAD_CANCEL_ENABLE);
|
||||
|
||||
return r == 0;
|
||||
#else
|
||||
if(!state){
|
||||
*was_cancellable = EINA_TRUE;
|
||||
return EINA_FALSE;
|
||||
}else{
|
||||
*was_cancellable = EINA_TRUE;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_thread_cancel_checkpoint(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
pthread_testcancel();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
EAPI void *
|
||||
|
@ -281,3 +198,40 @@ eina_thread_shutdown(void)
|
|||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void *_eina_internal_call(void *context)
|
||||
{
|
||||
Eina_Thread_Call *c = context;
|
||||
void *r;
|
||||
#ifdef _WIN32
|
||||
HANDLE self;
|
||||
#else
|
||||
pthread_t self;
|
||||
#endif
|
||||
|
||||
// Default this thread to not cancellable as per Eina documentation
|
||||
eina_thread_cancellable_set(EINA_FALSE, NULL);
|
||||
|
||||
EINA_THREAD_CLEANUP_PUSH(free, c);
|
||||
|
||||
if (c->prio == EINA_THREAD_BACKGROUND || c->prio == EINA_THREAD_IDLE)
|
||||
eina_sched_prio_drop();
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
self = GetCurrentThread();
|
||||
#else
|
||||
self = pthread_self();
|
||||
#endif
|
||||
|
||||
//self = GetCurrentThreadId();
|
||||
//self = GetCurrentThread();
|
||||
|
||||
_eina_debug_thread_add(&self);
|
||||
EINA_THREAD_CLEANUP_PUSH(_eina_debug_thread_del, &self);
|
||||
r = c->func((void*) c->data, eina_thread_self());
|
||||
EINA_THREAD_CLEANUP_POP(EINA_TRUE);
|
||||
EINA_THREAD_CLEANUP_POP(EINA_TRUE);
|
||||
|
||||
return r;
|
||||
}
|
|
@ -336,8 +336,21 @@ typedef void *(*Eina_Thread_Cancellable_Run_Cb)(void *data);
|
|||
*
|
||||
* @since 1.19
|
||||
*/
|
||||
|
||||
EAPI void *eina_thread_cancellable_run(Eina_Thread_Cancellable_Run_Cb cb, Eina_Free_Cb cleanup_cb, void *data);
|
||||
|
||||
|
||||
typedef struct _Eina_Thread_Call Eina_Thread_Call;
|
||||
struct _Eina_Thread_Call
|
||||
{
|
||||
Eina_Thread_Cb func;
|
||||
const void *data;
|
||||
|
||||
Eina_Thread_Priority prio;
|
||||
int affinity;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2012 Cedric Bail
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eina_config.h"
|
||||
#include "eina_lock.h" /* it will include pthread.h with proper flags */
|
||||
#include "eina_thread.h"
|
||||
#include "eina_sched.h"
|
||||
#include "eina_cpu.h"
|
||||
|
||||
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
|
||||
#include "eina_safety_checks.h"
|
||||
|
||||
#include "eina_debug_private.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#ifndef _WIN32
|
||||
# include <signal.h>
|
||||
#endif
|
||||
# include <string.h>
|
||||
|
||||
#if defined(EINA_HAVE_PTHREAD_AFFINITY) || defined(EINA_HAVE_PTHREAD_SETNAME)
|
||||
#ifndef __linux__
|
||||
#include <pthread_np.h>
|
||||
#define cpu_set_t cpuset_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static inline void *
|
||||
_eina_thread_join(Eina_Thread t)
|
||||
{
|
||||
void *ret = NULL;
|
||||
int err = pthread_join((pthread_t)t, &ret);
|
||||
|
||||
if (err == 0) return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_eina_thread_create(Eina_Thread *t, int affinity, void *(*func)(void *data), void *data)
|
||||
{
|
||||
int err;
|
||||
pthread_attr_t attr;
|
||||
#ifndef _WIN32
|
||||
sigset_t oldset, newset;
|
||||
#endif
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
if (affinity >= 0)
|
||||
{
|
||||
#ifdef EINA_HAVE_PTHREAD_AFFINITY
|
||||
cpu_set_t cpu;
|
||||
|
||||
CPU_ZERO(&cpu);
|
||||
CPU_SET(affinity, &cpu);
|
||||
pthread_attr_setaffinity_np(&attr, sizeof(cpu), &cpu);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* setup initial locks */
|
||||
#ifndef _WIN32
|
||||
sigemptyset(&newset);
|
||||
sigaddset(&newset, SIGPIPE);
|
||||
sigaddset(&newset, SIGALRM);
|
||||
sigaddset(&newset, SIGCHLD);
|
||||
sigaddset(&newset, SIGUSR1);
|
||||
sigaddset(&newset, SIGUSR2);
|
||||
sigaddset(&newset, SIGHUP);
|
||||
sigaddset(&newset, SIGQUIT);
|
||||
sigaddset(&newset, SIGINT);
|
||||
sigaddset(&newset, SIGTERM);
|
||||
# ifdef SIGPWR
|
||||
sigaddset(&newset, SIGPWR);
|
||||
# endif
|
||||
pthread_sigmask(SIG_BLOCK, &newset, &oldset);
|
||||
#endif
|
||||
err = pthread_create((pthread_t *)t, &attr, func, data);
|
||||
#ifndef _WIN32
|
||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
||||
#endif
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
if (err == 0) return EINA_TRUE;
|
||||
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static inline Eina_Bool
|
||||
_eina_thread_equal(Eina_Thread t1, Eina_Thread t2)
|
||||
{
|
||||
return pthread_equal((pthread_t)t1, (pthread_t)t2);
|
||||
}
|
||||
|
||||
static inline Eina_Thread
|
||||
_eina_thread_self(void)
|
||||
{
|
||||
return (Eina_Thread)pthread_self();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static void *
|
||||
_eina_internal_call(void *context)
|
||||
{
|
||||
Eina_Thread_Call *c = context;
|
||||
void *r;
|
||||
pthread_t self;
|
||||
|
||||
// Default this thread to not cancellable as per Eina documentation
|
||||
eina_thread_cancellable_set(EINA_FALSE, NULL);
|
||||
|
||||
EINA_THREAD_CLEANUP_PUSH(free, c);
|
||||
|
||||
if (c->prio == EINA_THREAD_BACKGROUND ||
|
||||
c->prio == EINA_THREAD_IDLE)
|
||||
eina_sched_prio_drop();
|
||||
|
||||
self = pthread_self();
|
||||
_eina_debug_thread_add(&self);
|
||||
EINA_THREAD_CLEANUP_PUSH(_eina_debug_thread_del, &self);
|
||||
r = c->func((void*) c->data, eina_thread_self());
|
||||
EINA_THREAD_CLEANUP_POP(EINA_TRUE);
|
||||
EINA_THREAD_CLEANUP_POP(EINA_TRUE);
|
||||
|
||||
return r;
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,174 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2012 Cedric Bail
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "eina_config.h"
|
||||
#include "eina_lock.h" /* it will include pthread.h with proper flags */
|
||||
|
||||
#include "eina_sched.h"
|
||||
#include "eina_cpu.h"
|
||||
#include "eina_thread.h"
|
||||
/* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
|
||||
#include "eina_safety_checks.h"
|
||||
|
||||
#include "eina_debug_private.h"
|
||||
|
||||
# include <Windows.h>
|
||||
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef _WIN32
|
||||
# include <signal.h>
|
||||
#endif
|
||||
# include <string.h>
|
||||
|
||||
#if defined(EINA_HAVE_PTHREAD_AFFINITY) || defined(EINA_HAVE_PTHREAD_SETNAME)
|
||||
#ifndef __linux__
|
||||
#define cpu_set_t cpuset_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct _Eina_win32_thread_attr{
|
||||
void *data;
|
||||
void *(*func)(void *data);
|
||||
|
||||
}Eina_win32_thread_attr;
|
||||
|
||||
|
||||
inline void *
|
||||
_eina_thread_join(Eina_Thread t)
|
||||
{
|
||||
//void *ret = NULL;
|
||||
int timeout_millis = 10000;
|
||||
int ret = WaitForSingleObject(t,timeout_millis);//int ret = pthread_join((pthread_t)t, &ret);
|
||||
|
||||
if (ret != 0) return ret;//if (ret == 0) return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DWORD WINAPI _eina_thread_func(void *params)
|
||||
{
|
||||
// // Code
|
||||
//Eina_Thread_Call *c = params;
|
||||
//void *r;
|
||||
//r = c->func((void*) c->data, eina_thread_self());
|
||||
//return (DWORD) r;
|
||||
//return (DWORD) _eina_internal_call(params);
|
||||
|
||||
return (DWORD) ((Eina_win32_thread_attr *)params)->func( (void*) ((Eina_win32_thread_attr *)params)->data);
|
||||
}
|
||||
|
||||
|
||||
void _eina_thread_set_priority(Eina_Thread_Priority prio, Eina_Thread *t){
|
||||
//HANDLE hThread;
|
||||
int nPriority;
|
||||
|
||||
switch(prio){
|
||||
case EINA_THREAD_URGENT: nPriority =THREAD_PRIORITY_HIGHEST;
|
||||
case EINA_THREAD_NORMAL: nPriority = THREAD_PRIORITY_NORMAL;
|
||||
case EINA_THREAD_BACKGROUND: nPriority = THREAD_PRIORITY_BELOW_NORMAL;
|
||||
case EINA_THREAD_IDLE: nPriority = THREAD_PRIORITY_IDLE;
|
||||
}
|
||||
|
||||
SetThreadPriority((HANDLE)*t,nPriority);
|
||||
}
|
||||
|
||||
inline Eina_Bool
|
||||
_eina_thread_create(Eina_Thread *t, int affinity, void *(*func)(void *data), void *data)
|
||||
{
|
||||
Eina_Bool ret;
|
||||
|
||||
LPDWORD threadID;
|
||||
|
||||
Eina_win32_thread_attr *thread_attr = (Eina_win32_thread_attr*) malloc(sizeof(Eina_win32_thread_attr));
|
||||
Eina_Thread_Call *c = (Eina_Thread_Call*)(data);
|
||||
|
||||
thread_attr->func = func;
|
||||
thread_attr->data = data;
|
||||
|
||||
*t =(HANDLE) CreateThread(NULL, 0, &_eina_thread_func,thread_attr,0,threadID);
|
||||
|
||||
free(thread_attr);
|
||||
|
||||
|
||||
|
||||
_eina_thread_set_priority(c->prio,t); //SetThreadPriority(*t, c->prio);
|
||||
|
||||
ret = (*t != NULL) ? EINA_TRUE : EINA_FALSE;
|
||||
|
||||
if(affinity >= 0 && ret){
|
||||
#ifdef EINA_HAVE_PTHREAD_AFFINITY
|
||||
cpu_set_t cpu;
|
||||
CPU_ZERO(&cpu);
|
||||
CPU_SET(affinity, &cpu);
|
||||
SetThreadAffinityMask(*t,(DWORD_PTR*)&cpu);
|
||||
#else
|
||||
SetThreadAffinityMask(*t,(DWORD_PTR*)&affinity);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline Eina_Bool
|
||||
_eina_thread_equal(Eina_Thread t1, Eina_Thread t2)
|
||||
{
|
||||
DWORD t1_thread_id = GetThreadId((HANDLE)t1);
|
||||
DWORD t2_thread_id = GetThreadId((HANDLE)t2);
|
||||
|
||||
return (t1_thread_id == t2_thread_id) ? EINA_TRUE : EINA_FALSE;
|
||||
//return pthread_equal((pthread_t)t1, (pthread_t)t2);
|
||||
}
|
||||
|
||||
inline Eina_Thread
|
||||
_eina_thread_self(void)
|
||||
{
|
||||
//return (Eina_Thread)GetCurrentThreadId();
|
||||
return (Eina_Thread)GetCurrentThread();
|
||||
//return (Eina_Thread)pthread_self();
|
||||
}
|
||||
|
||||
HRESULT _eina_thread_set_name_win32(Eina_Thread thread, char *buf){
|
||||
return SetThreadDescription((HANDLE)thread, (PCWSTR)buf);
|
||||
}
|
||||
|
||||
Eina_Bool _eina_thread_cancel(Eina_Thread thread){
|
||||
LPDWORD lpExitCode;
|
||||
Eina_Bool success = GetExitCodeThread((HANDLE)thread, lpExitCode);
|
||||
|
||||
ExitThread(*lpExitCode);
|
||||
return success;
|
||||
//return SetThreadDescription((HANDLE)thread, (PCWSTR)buf);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -199,8 +199,10 @@ sources = [
|
|||
|
||||
if sys_windows == true
|
||||
sources += 'eina_file_win32.c'
|
||||
sources += 'eina_thread_win32.c'
|
||||
else
|
||||
sources += 'eina_file.c'
|
||||
sources += 'eina_thread_posix.c'
|
||||
endif
|
||||
|
||||
eina_config = configuration_data()
|
||||
|
@ -410,4 +412,4 @@ pkgconfig.generate(eina_lib,
|
|||
version : version_major + '.' + version_minor + '.' + version_micro,
|
||||
libraries : eina_pub_deps,
|
||||
)
|
||||
endif
|
||||
endif
|
Loading…
Reference in New Issue