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 /*
2 * Copyright (c) 2011 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #ifndef VPX_ONCE_H
11 #define VPX_ONCE_H
13 #include "vpx_config.h"
15 #if CONFIG_MULTITHREAD && defined(_WIN32)
16 #include <windows.h>
17 #include <stdlib.h>
18 static void once(void (*func)(void))
19 {
20 static CRITICAL_SECTION *lock;
21 static LONG waiters;
22 static int done;
23 void *lock_ptr = &lock;
25 /* If the initialization is complete, return early. This isn't just an
26 * optimization, it prevents races on the destruction of the global
27 * lock.
28 */
29 if(done)
30 return;
32 InterlockedIncrement(&waiters);
34 /* Get a lock. We create one and try to make it the one-true-lock,
35 * throwing it away if we lost the race.
36 */
38 {
39 /* Scope to protect access to new_lock */
40 CRITICAL_SECTION *new_lock = malloc(sizeof(CRITICAL_SECTION));
41 InitializeCriticalSection(new_lock);
42 if (InterlockedCompareExchangePointer(lock_ptr, new_lock, NULL) != NULL)
43 {
44 DeleteCriticalSection(new_lock);
45 free(new_lock);
46 }
47 }
49 /* At this point, we have a lock that can be synchronized on. We don't
50 * care which thread actually performed the allocation.
51 */
53 EnterCriticalSection(lock);
55 if (!done)
56 {
57 func();
58 done = 1;
59 }
61 LeaveCriticalSection(lock);
63 /* Last one out should free resources. The destructed objects are
64 * protected by checking if(done) above.
65 */
66 if(!InterlockedDecrement(&waiters))
67 {
68 DeleteCriticalSection(lock);
69 free(lock);
70 lock = NULL;
71 }
72 }
75 #elif CONFIG_MULTITHREAD && HAVE_PTHREAD_H
76 #include <pthread.h>
77 static void once(void (*func)(void))
78 {
79 static pthread_once_t lock = PTHREAD_ONCE_INIT;
80 pthread_once(&lock, func);
81 }
84 #else
85 /* No-op version that performs no synchronization. vp8_rtcd() is idempotent,
86 * so as long as your platform provides atomic loads/stores of pointers
87 * no synchronization is strictly necessary.
88 */
90 static void once(void (*func)(void))
91 {
92 static int done;
94 if(!done)
95 {
96 func();
97 done = 1;
98 }
99 }
100 #endif
102 #endif