media/libvpx/vpx_ports/vpx_once.h

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.

     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

mercurial