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