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

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "cpr.h"
michael@0 6 #include "cpr_stdlib.h"
michael@0 7 #include "cpr_stdio.h"
michael@0 8 #include <pthread.h>
michael@0 9 #include <errno.h>
michael@0 10 #include <unistd.h>
michael@0 11 #include <sys/resource.h>
michael@0 12 #include "thread_monitor.h"
michael@0 13 #include "prtypes.h"
michael@0 14 #include "mozilla/Assertions.h"
michael@0 15
michael@0 16 #define ANDROID_MIN_THREAD_PRIORITY (-20) /* tbd: check MV linux: current val from Larry port */
michael@0 17 #define ANDROID_MAX_THREAD_PRIORITY (+19) /* tbd: check MV linux. current val from Larry port */
michael@0 18
michael@0 19 void CSFLogRegisterThread(const cprThread_t thread);
michael@0 20
michael@0 21 /**
michael@0 22 * cprCreateThread
michael@0 23 *
michael@0 24 * @brief Create a thread
michael@0 25 *
michael@0 26 * The cprCreateThread function creates another execution thread within the
michael@0 27 * current process. If the input parameter "name" is present, then this is used
michael@0 28 * for debugging purposes. The startRoutine is the address of the function where
michael@0 29 * the thread execution begins. The start routine prototype is defined as
michael@0 30 * follows
michael@0 31 * @code
michael@0 32 * int32_t (*cprThreadStartRoutine)(void* data)
michael@0 33 * @endcode
michael@0 34 *
michael@0 35 * @param[in] name - name of the thread created (optional)
michael@0 36 * @param[in] startRoutine - function where thread execution begins
michael@0 37 * @param[in] stackSize - size of the thread's stack
michael@0 38 * @param[in] priority - thread's execution priority
michael@0 39 * @param[in] data - parameter to pass to startRoutine
michael@0 40 *
michael@0 41 * Return Value: Thread handle or NULL if creation failed.
michael@0 42 */
michael@0 43 cprThread_t
michael@0 44 cprCreateThread (const char *name,
michael@0 45 cprThreadStartRoutine startRoutine,
michael@0 46 uint16_t stackSize,
michael@0 47 uint16_t priority,
michael@0 48 void *data)
michael@0 49 {
michael@0 50 static const char fname[] = "cprCreateThread";
michael@0 51 static uint16_t id = 0;
michael@0 52 cpr_thread_t *threadPtr;
michael@0 53 pthread_t threadId;
michael@0 54 pthread_attr_t attr;
michael@0 55
michael@0 56 CPR_INFO("%s: creating '%s' thread\n", fname, name);
michael@0 57
michael@0 58 /* Malloc memory for a new thread */
michael@0 59 threadPtr = (cpr_thread_t *)cpr_malloc(sizeof(cpr_thread_t));
michael@0 60 if (threadPtr != NULL) {
michael@0 61 if (pthread_attr_init(&attr) != 0) {
michael@0 62
michael@0 63 CPR_ERROR("%s - Failed to init attribute for thread %s\n",
michael@0 64 fname, name);
michael@0 65 cpr_free(threadPtr);
michael@0 66 return (cprThread_t)NULL;
michael@0 67 }
michael@0 68
michael@0 69 if (pthread_attr_setstacksize(&attr, stackSize) != 0) {
michael@0 70 CPR_ERROR("%s - Invalid stacksize %d specified for thread %s\n",
michael@0 71 fname, stackSize, name);
michael@0 72 cpr_free(threadPtr);
michael@0 73 return (cprThread_t)NULL;
michael@0 74 }
michael@0 75
michael@0 76 if (pthread_create(&threadId, &attr, startRoutine, data) != 0) {
michael@0 77 CPR_ERROR("%s - Creation of thread %s failed: %d\n",
michael@0 78 fname, name, errno);
michael@0 79 cpr_free(threadPtr);
michael@0 80 return (cprThread_t)NULL;
michael@0 81 }
michael@0 82
michael@0 83 /* Assign name to CPR if one was passed in */
michael@0 84 if (name != NULL) {
michael@0 85 threadPtr->name = name;
michael@0 86 }
michael@0 87
michael@0 88 /*
michael@0 89 * TODO - It would be nice for CPR to keep a linked
michael@0 90 * list of running threads for debugging purposes
michael@0 91 * such as a show command or walking the list to ensure
michael@0 92 * that an application does not attempt to create
michael@0 93 * the same thread twice.
michael@0 94 */
michael@0 95 threadPtr->u.handleInt = threadId;
michael@0 96 threadPtr->threadId = ++id;
michael@0 97 CSFLogRegisterThread(threadPtr);
michael@0 98 return (cprThread_t)threadPtr;
michael@0 99 }
michael@0 100
michael@0 101 /* Malloc failed */
michael@0 102 CPR_ERROR("%s - Malloc for thread %s failed.\n", fname, name);
michael@0 103 errno = ENOMEM;
michael@0 104 return (cprThread_t)NULL;
michael@0 105 }
michael@0 106
michael@0 107 /*
michael@0 108 * cprJoinThread
michael@0 109 *
michael@0 110 * wait for thread termination
michael@0 111 */
michael@0 112 void cprJoinThread(cprThread_t thread)
michael@0 113 {
michael@0 114 cpr_thread_t *cprThreadPtr;
michael@0 115
michael@0 116 cprThreadPtr = (cpr_thread_t *) thread;
michael@0 117 MOZ_ASSERT(cprThreadPtr);
michael@0 118 pthread_join(cprThreadPtr->u.handleInt, NULL);
michael@0 119 }
michael@0 120
michael@0 121 /**
michael@0 122 * cprDestroyThread
michael@0 123 *
michael@0 124 * @brief Destroys the thread passed in.
michael@0 125 *
michael@0 126 * The cprDestroyThread function is called to destroy a thread. The thread
michael@0 127 * parameter may be any valid thread including the calling thread itself.
michael@0 128 *
michael@0 129 * @param[in] thread - thread to destroy.
michael@0 130 *
michael@0 131 * @return CPR_SUCCESS or CPR_FAILURE. errno should be set for FAILURE case.
michael@0 132 *
michael@0 133 * @note In Linux there will never be a success indication as the
michael@0 134 * calling thread will have been terminated.
michael@0 135 */
michael@0 136 cprRC_t
michael@0 137 cprDestroyThread (cprThread_t thread)
michael@0 138 {
michael@0 139 cpr_thread_t *cprThreadPtr;
michael@0 140
michael@0 141 cprThreadPtr = (cpr_thread_t *) thread;
michael@0 142 if (cprThreadPtr) {
michael@0 143 /*
michael@0 144 * Make sure thread is trying to destroy itself.
michael@0 145 */
michael@0 146 if ((pthread_t) cprThreadPtr->u.handleInt == pthread_self()) {
michael@0 147 CPR_INFO("%s: Destroying Thread %d", __FUNCTION__, cprThreadPtr->threadId);
michael@0 148 pthread_exit(NULL);
michael@0 149 return CPR_SUCCESS;
michael@0 150 }
michael@0 151
michael@0 152 CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.",
michael@0 153 __FUNCTION__);
michael@0 154 MOZ_ASSERT(PR_FALSE);
michael@0 155 errno = EINVAL;
michael@0 156 return CPR_FAILURE;
michael@0 157 }
michael@0 158
michael@0 159 CPR_ERROR("%s - NULL pointer passed in.", __FUNCTION__);
michael@0 160 MOZ_ASSERT(PR_FALSE);
michael@0 161 errno = EINVAL;
michael@0 162 return CPR_FAILURE;
michael@0 163 }
michael@0 164
michael@0 165 /**
michael@0 166 * cprAdjustRelativeThreadPriority
michael@0 167 *
michael@0 168 * @brief The function sets the relative thread priority up or down by the given value.
michael@0 169 *
michael@0 170 * This function is used pSIPCC to set up the thread priority. The values of the
michael@0 171 * priority range from -20 (Maximum priority) to +19 (Minimum priority).
michael@0 172 *
michael@0 173 * @param[in] relPri - nice value of the thread -20 is MAX and 19 is MIN
michael@0 174 *
michael@0 175 * @return CPR_SUCCESS or CPR_FAILURE
michael@0 176 */
michael@0 177 cprRC_t
michael@0 178 cprAdjustRelativeThreadPriority (int relPri)
michael@0 179 {
michael@0 180 const char *fname = "cprAdjustRelativeThreadPriority";
michael@0 181
michael@0 182 if (setpriority(PRIO_PROCESS, 0, relPri) == -1) {
michael@0 183 CPR_ERROR("%s: could not set the nice..err=%d\n",
michael@0 184 fname, errno);
michael@0 185 return CPR_FAILURE;
michael@0 186 }
michael@0 187 return CPR_SUCCESS;
michael@0 188 }
michael@0 189
michael@0 190 /**
michael@0 191 * @}
michael@0 192 * @addtogroup ThreadInternal Helper functions for implementing threads in CPR
michael@0 193 * @ingroup Threads
michael@0 194 * @brief Helper functions used by CPR for thread implementation
michael@0 195 *
michael@0 196 * @{
michael@0 197 */
michael@0 198
michael@0 199 /**
michael@0 200 * cprGetThreadId
michael@0 201 *
michael@0 202 * @brief Return the pthread ID for the given CPR thread.
michael@0 203 *
michael@0 204 * @param[in] thread - thread to query
michael@0 205 *
michael@0 206 * @return Thread's Id or zero(0)
michael@0 207 *
michael@0 208 */
michael@0 209 pthread_t
michael@0 210 cprGetThreadId (cprThread_t thread)
michael@0 211 {
michael@0 212 if (thread) {
michael@0 213 return ((cpr_thread_t *)thread)->u.handleInt;
michael@0 214 }
michael@0 215 return 0;
michael@0 216 }
michael@0 217 /**
michael@0 218 * @}
michael@0 219 */

mercurial