/* The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-) Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifndef OSIP_MONOTHREAD #include #include #if defined(__rtems__) #include #endif #if !defined(__rtems__) #if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(HAVE_PTHREAD_WIN32) #if defined _WIN32_WCE #define _beginthreadex CreateThread #define _endthreadex ExitThread #elif defined WIN32 #include #endif #endif /* stack size is only needed on VxWorks. */ #ifndef __VXWORKS_OS__ #if defined(HAVE_PTHREAD) || defined(HAVE_PTH_PTHREAD_H) || defined(HAVE_PTHREAD_WIN32) struct osip_thread *osip_thread_create(int stacksize, void *(*func)(void *), void *arg) { int i; osip_thread_t *thread = (osip_thread_t *) osip_malloc(sizeof(osip_thread_t)); if (thread == NULL) return NULL; i = pthread_create(thread, NULL, func, (void *) arg); if (i != 0) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "Error while creating a new thread\n")); osip_free(thread); return NULL; } return (struct osip_thread *) thread; } int osip_thread_set_priority(struct osip_thread *thread, int priority) { return OSIP_SUCCESS; } int osip_thread_join(struct osip_thread *_thread) { osip_thread_t *thread = (osip_thread_t *) _thread; if (thread == NULL) return OSIP_BADPARAMETER; return pthread_join(*thread, NULL); } void osip_thread_exit() { #if !defined(__arc__) pthread_exit(NULL); #endif } #endif #endif #if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(HAVE_PTHREAD_WIN32) #if defined(HAVE_CPP11_THREAD) #include #include struct osip_thread *osip_thread_create(int stacksize, void *(*func)(void *), void *arg) { osip_thread_t *thread = (osip_thread_t *) osip_malloc(sizeof(osip_thread_t)); if (thread == NULL) return NULL; thread->h = new std::thread(func, arg); if (thread->h == 0) { osip_free(thread); return NULL; } return (struct osip_thread *) thread; } int osip_thread_join(struct osip_thread *_thread) { osip_thread_t *thread = (osip_thread_t *) _thread; std::thread *th; if (thread == NULL) return OSIP_BADPARAMETER; th = (std::thread *) thread->h; th->join(); delete th; thread->h = NULL; return (0); } void osip_thread_exit() { } int osip_thread_set_priority(struct osip_thread *thread, int priority) { return OSIP_SUCCESS; } #else struct osip_thread *osip_thread_create(int stacksize, void *(*func)(void *), void *arg) { osip_thread_t *thread = (osip_thread_t *) osip_malloc(sizeof(osip_thread_t)); if (thread == NULL) return NULL; thread->h = (HANDLE) _beginthreadex(NULL, /* default security attr */ 0, /* use default one */ (unsigned(__stdcall *)(void *)) func, arg, 0, &(thread->id)); if (thread->h == 0) { osip_free(thread); return NULL; } return (struct osip_thread *) thread; } int osip_thread_join(struct osip_thread *_thread) { int i; osip_thread_t *thread = (osip_thread_t *) _thread; if (thread == NULL) return OSIP_BADPARAMETER; i = WaitForSingleObject(thread->h, INFINITE); if (i == WAIT_OBJECT_0) { /* fprintf (stdout, "thread joined!\n"); */ } else { /* fprintf (stdout, "ERROR!! thread joined ERROR!!\n"); */ return OSIP_UNDEFINED_ERROR; } CloseHandle(thread->h); return (0); } void osip_thread_exit() { /* ExitThread(0); */ _endthreadex(0); } int osip_thread_set_priority(struct osip_thread *thread, int priority) { return OSIP_SUCCESS; } #endif #endif #ifndef __VXWORKS_OS__ #ifdef __PSOS__ struct osip_thread *osip_thread_create(int stacksize, void *(*func)(void *), void *arg) { osip_thread_t *thread = (osip_thread_t *) osip_malloc(sizeof(osip_thread_t)); if (thread == NULL) return (NULL); if (t_create("sip", 150, stacksize, 0, 0, &thread->tid) != 0) { osip_free(thread); return (NULL); } if (t_start(thread->tid, T_PREEMPT | T_ISR, func, 0) != 0) { osip_free(thread); return (NULL); } return (struct osip_thread *) thread; } int osip_thread_set_priority(struct osip_thread *_thread, int priority) { unsigned long oldprio; osip_thread_t *thread = (osip_thread_t *) _thread; if (thread == NULL) return OSIP_BADPARAMETER; t_set_pri(thread->tid, priority, &oldprio); return OSIP_SUCCESS; } int osip_thread_join(struct osip_thread *_thread) { osip_thread_t *thread = (osip_thread_t *) _thread; if (thread == NULL) return OSIP_BADPARAMETER; t_delete(thread->tid); return (0); } void osip_thread_exit() { t_delete(0); } #endif #endif #ifdef __VXWORKS_OS__ struct osip_thread *osip_thread_create(int stacksize, void *(*func)(void *), void *arg) { osip_thread_t *thread = (osip_thread_t *) osip_malloc(sizeof(osip_thread_t)); if (thread == NULL) return NULL; thread->id = taskSpawn(NULL, 5, 0, stacksize, (FUNCPTR) func, (int) arg, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (thread->id < 0) osip_free(thread); return (struct osip_thread *) thread; } int osip_thread_set_priority(struct osip_thread *_thread, int priority) { osip_thread_t *thread = (osip_thread_t *) _thread; if (thread == NULL) return OSIP_BADPARAMETER; taskPrioritySet(thread->id, 1); return OSIP_SUCCESS; } int osip_thread_join(struct osip_thread *_thread) { osip_thread_t *thread = (osip_thread_t *) _thread; if (thread == NULL) return OSIP_BADPARAMETER; return taskDelete(thread->id); } void osip_thread_exit() { /*?? */ } #endif #endif /* #ifndef __rtems__ */ #if defined(__rtems__) struct osip_thread *osip_thread_create(int stacksize, void *(*func)(void *), void *arg) { rtems_status_code status; osip_thread_t *thread = (osip_thread_t *) osip_malloc(sizeof(osip_thread_t)); if (thread == NULL) return NULL; status = rtems_task_create(rtems_build_name('S', 'I', 'P', 'T'), 100, stacksize, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &thread->tid); if (status == RTEMS_SUCCESSFUL) { status = rtems_task_start(thread->tid, (rtems_task_entry) func, (rtems_task_argument) arg); } if (status != RTEMS_SUCCESSFUL) { osip_free(thread); thread = NULL; } return (struct osip_thread *) thread; } int osip_thread_set_priority(struct osip_thread *_thread, int priority) { osip_thread_t *thread = (osip_thread_t *) _thread; rtems_task_priority old; if (thread != NULL) { return rtems_task_set_priority(thread->tid, priority, &old); } return OSIP_SUCCESS; } int osip_thread_join(struct osip_thread *_thread) { osip_thread_t *thread = (osip_thread_t *) _thread; if (thread == NULL) { return OSIP_BADPARAMETER; } return rtems_task_delete(thread->tid); } void osip_thread_exit() { rtems_task_delete(RTEMS_SELF); } #endif #endif /* #ifndef OSIP_MONOTHREAD */