media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_threads.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,219 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "cpr.h"
     1.9 +#include "cpr_stdlib.h"
    1.10 +#include "cpr_stdio.h"
    1.11 +#include <pthread.h>
    1.12 +#include <errno.h>
    1.13 +#include <unistd.h>
    1.14 +#include <sys/resource.h>
    1.15 +#include "thread_monitor.h"
    1.16 +#include "prtypes.h"
    1.17 +#include "mozilla/Assertions.h"
    1.18 +
    1.19 +#define ANDROID_MIN_THREAD_PRIORITY (-20)	/* tbd: check MV linux: current val from Larry port */
    1.20 +#define ANDROID_MAX_THREAD_PRIORITY (+19)	/* tbd: check MV linux. current val from Larry port */
    1.21 +
    1.22 +void CSFLogRegisterThread(const cprThread_t thread);
    1.23 +
    1.24 +/**
    1.25 + * cprCreateThread
    1.26 + *
    1.27 + * @brief Create a thread
    1.28 + *
    1.29 + *  The cprCreateThread function creates another execution thread within the
    1.30 + *  current process. If the input parameter "name" is present, then this is used
    1.31 + *  for debugging purposes. The startRoutine is the address of the function where
    1.32 + *  the thread execution begins. The start routine prototype is defined as
    1.33 + *  follows
    1.34 + *  @code
    1.35 + *     int32_t (*cprThreadStartRoutine)(void* data)
    1.36 + *  @endcode
    1.37 + *
    1.38 + * @param[in]  name         - name of the thread created (optional)
    1.39 + * @param[in]  startRoutine - function where thread execution begins
    1.40 + * @param[in]  stackSize    - size of the thread's stack
    1.41 + * @param[in]  priority     - thread's execution priority
    1.42 + * @param[in]  data         - parameter to pass to startRoutine
    1.43 + *
    1.44 + * Return Value: Thread handle or NULL if creation failed.
    1.45 + */
    1.46 +cprThread_t
    1.47 +cprCreateThread (const char *name,
    1.48 +                 cprThreadStartRoutine startRoutine,
    1.49 +                 uint16_t stackSize,
    1.50 +                 uint16_t priority,
    1.51 +                 void *data)
    1.52 +{
    1.53 +    static const char fname[] = "cprCreateThread";
    1.54 +    static uint16_t id = 0;
    1.55 +    cpr_thread_t *threadPtr;
    1.56 +    pthread_t threadId;
    1.57 +    pthread_attr_t attr;
    1.58 +
    1.59 +    CPR_INFO("%s: creating '%s' thread\n", fname, name);
    1.60 +
    1.61 +    /* Malloc memory for a new thread */
    1.62 +    threadPtr = (cpr_thread_t *)cpr_malloc(sizeof(cpr_thread_t));
    1.63 +    if (threadPtr != NULL) {
    1.64 +        if (pthread_attr_init(&attr) != 0) {
    1.65 +
    1.66 +            CPR_ERROR("%s - Failed to init attribute for thread %s\n",
    1.67 +                      fname, name);
    1.68 +            cpr_free(threadPtr);
    1.69 +            return (cprThread_t)NULL;
    1.70 +        }
    1.71 +
    1.72 +        if (pthread_attr_setstacksize(&attr, stackSize) != 0) {
    1.73 +            CPR_ERROR("%s - Invalid stacksize %d specified for thread %s\n",
    1.74 +                      fname, stackSize, name);
    1.75 +            cpr_free(threadPtr);
    1.76 +            return (cprThread_t)NULL;
    1.77 +        }
    1.78 +
    1.79 +        if (pthread_create(&threadId, &attr, startRoutine, data) != 0) {
    1.80 +            CPR_ERROR("%s - Creation of thread %s failed: %d\n",
    1.81 +                      fname, name, errno);
    1.82 +            cpr_free(threadPtr);
    1.83 +            return (cprThread_t)NULL;
    1.84 +        }
    1.85 +
    1.86 +        /* Assign name to CPR if one was passed in */
    1.87 +        if (name != NULL) {
    1.88 +            threadPtr->name = name;
    1.89 +        }
    1.90 +
    1.91 +        /*
    1.92 +         * TODO - It would be nice for CPR to keep a linked
    1.93 +         * list of running threads for debugging purposes
    1.94 +         * such as a show command or walking the list to ensure
    1.95 +         * that an application does not attempt to create
    1.96 +         * the same thread twice.
    1.97 +         */
    1.98 +        threadPtr->u.handleInt = threadId;
    1.99 +        threadPtr->threadId = ++id;
   1.100 +        CSFLogRegisterThread(threadPtr);
   1.101 +        return (cprThread_t)threadPtr;
   1.102 +    }
   1.103 +
   1.104 +    /* Malloc failed */
   1.105 +    CPR_ERROR("%s - Malloc for thread %s failed.\n", fname, name);
   1.106 +    errno = ENOMEM;
   1.107 +    return (cprThread_t)NULL;
   1.108 +}
   1.109 +
   1.110 +/*
   1.111 + * cprJoinThread
   1.112 + *
   1.113 + * wait for thread termination
   1.114 + */
   1.115 +void cprJoinThread(cprThread_t thread)
   1.116 +{
   1.117 +    cpr_thread_t *cprThreadPtr;
   1.118 +
   1.119 +    cprThreadPtr = (cpr_thread_t *) thread;
   1.120 +    MOZ_ASSERT(cprThreadPtr);
   1.121 +    pthread_join(cprThreadPtr->u.handleInt, NULL);
   1.122 +}
   1.123 +
   1.124 +/**
   1.125 + * cprDestroyThread
   1.126 + *
   1.127 + * @brief Destroys the thread passed in.
   1.128 + *
   1.129 + * The cprDestroyThread function is called to destroy a thread. The thread
   1.130 + * parameter may be any valid thread including the calling thread itself.
   1.131 + *
   1.132 + * @param[in] thread - thread to destroy.
   1.133 + *
   1.134 + * @return CPR_SUCCESS or CPR_FAILURE. errno should be set for FAILURE case.
   1.135 + *
   1.136 + * @note In Linux there will never be a success indication as the
   1.137 + *       calling thread will have been terminated.
   1.138 + */
   1.139 +cprRC_t
   1.140 +cprDestroyThread (cprThread_t thread)
   1.141 +{
   1.142 +    cpr_thread_t *cprThreadPtr;
   1.143 +
   1.144 +    cprThreadPtr = (cpr_thread_t *) thread;
   1.145 +    if (cprThreadPtr) {
   1.146 +        /*
   1.147 +         * Make sure thread is trying to destroy itself.
   1.148 +         */
   1.149 +        if ((pthread_t) cprThreadPtr->u.handleInt == pthread_self()) {
   1.150 +            CPR_INFO("%s: Destroying Thread %d", __FUNCTION__, cprThreadPtr->threadId);
   1.151 +            pthread_exit(NULL);
   1.152 +            return CPR_SUCCESS;
   1.153 +        }
   1.154 +
   1.155 +        CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.",
   1.156 +                  __FUNCTION__);
   1.157 +        MOZ_ASSERT(PR_FALSE);
   1.158 +        errno = EINVAL;
   1.159 +        return CPR_FAILURE;
   1.160 +    }
   1.161 +
   1.162 +    CPR_ERROR("%s - NULL pointer passed in.", __FUNCTION__);
   1.163 +    MOZ_ASSERT(PR_FALSE);
   1.164 +    errno = EINVAL;
   1.165 +    return CPR_FAILURE;
   1.166 +}
   1.167 +
   1.168 +/**
   1.169 + * cprAdjustRelativeThreadPriority
   1.170 + *
   1.171 + * @brief The function sets the relative thread priority up or down by the given value.
   1.172 + *
   1.173 + * This function is used pSIPCC to set up the thread priority. The values of the
   1.174 + * priority range from -20 (Maximum priority) to +19 (Minimum priority).
   1.175 + *
   1.176 + * @param[in] relPri - nice value of the thread -20 is MAX and 19 is MIN
   1.177 + *
   1.178 + * @return CPR_SUCCESS or CPR_FAILURE
   1.179 + */
   1.180 +cprRC_t
   1.181 +cprAdjustRelativeThreadPriority (int relPri)
   1.182 +{
   1.183 +    const char *fname = "cprAdjustRelativeThreadPriority";
   1.184 +
   1.185 +    if (setpriority(PRIO_PROCESS, 0, relPri) == -1) {
   1.186 +        CPR_ERROR("%s: could not set the nice..err=%d\n",
   1.187 +                  fname, errno);
   1.188 +        return CPR_FAILURE;
   1.189 +    }
   1.190 +    return CPR_SUCCESS;
   1.191 +}
   1.192 +
   1.193 +/**
   1.194 + * @}
   1.195 + * @addtogroup ThreadInternal Helper functions for implementing threads in CPR
   1.196 + * @ingroup Threads
   1.197 + * @brief Helper functions used by CPR for thread implementation
   1.198 + *
   1.199 + * @{
   1.200 + */
   1.201 +
   1.202 +/**
   1.203 + * cprGetThreadId
   1.204 + *
   1.205 + * @brief Return the pthread ID for the given CPR thread.
   1.206 + *
   1.207 + * @param[in] thread - thread to query
   1.208 + *
   1.209 + * @return Thread's Id or zero(0)
   1.210 + *
   1.211 + */
   1.212 +pthread_t
   1.213 +cprGetThreadId (cprThread_t thread)
   1.214 +{
   1.215 +    if (thread) {
   1.216 +        return ((cpr_thread_t *)thread)->u.handleInt;
   1.217 +    }
   1.218 +    return 0;
   1.219 +}
   1.220 +/**
   1.221 +  * @}
   1.222 +  */

mercurial