xpcom/build/PoisonIOInterposerBase.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim:set ts=2 sw=2 sts=2 ci et: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "mozilla/Mutex.h"
     8 #include "mozilla/Scoped.h"
    10 #include <algorithm>
    11 #include <vector>
    13 #include "PoisonIOInterposer.h"
    15 // Auxiliary method to convert file descriptors to ids
    16 #if defined(XP_WIN32)
    17 #include <io.h>
    18 inline intptr_t FileDescriptorToID(int aFd) {
    19   return _get_osfhandle(aFd);
    20 }
    21 #else
    22 inline intptr_t FileDescriptorToID(int aFd) {
    23   return aFd;
    24 }
    25 #endif /* if not XP_WIN32 */
    27 using namespace mozilla;
    29 namespace {
    30 struct DebugFilesAutoLockTraits {
    31   typedef PRLock *type;
    32   const static type empty() {
    33     return nullptr;
    34   }
    35   const static void release(type aL) {
    36     PR_Unlock(aL);
    37   }
    38 };
    40 class DebugFilesAutoLock : public Scoped<DebugFilesAutoLockTraits> {
    41   static PRLock *Lock;
    42 public:
    43   static void Clear();
    44   static PRLock *getDebugFileIDsLock() {
    45     // On windows this static is not thread safe, but we know that the first
    46     // call is from
    47     // * An early registration of a debug FD or
    48     // * The call to InitWritePoisoning.
    49     // Since the early debug FDs are logs created early in the main thread
    50     // and no writes are trapped before InitWritePoisoning, we are safe.
    51     if (!Lock) {
    52       Lock = PR_NewLock();
    53     }
    55     // We have to use something lower level than a mutex. If we don't, we
    56     // can get recursive in here when called from logging a call to free.
    57     return Lock;
    58   }
    60   DebugFilesAutoLock() :
    61     Scoped<DebugFilesAutoLockTraits>(getDebugFileIDsLock()) {
    62     PR_Lock(get());
    63   }
    64 };
    66 PRLock *DebugFilesAutoLock::Lock;
    67 void DebugFilesAutoLock::Clear() {
    68   MOZ_ASSERT(Lock != nullptr);
    69   Lock = nullptr;
    70 }
    72 // Return a vector used to hold the IDs of the current debug files. On unix
    73 // an ID is a file descriptor. On Windows it is a file HANDLE.
    74 std::vector<intptr_t>* getDebugFileIDs() {
    75   PR_ASSERT_CURRENT_THREAD_OWNS_LOCK(DebugFilesAutoLock::getDebugFileIDsLock());
    76   // We have to use new as some write happen during static destructors
    77   // so an static std::vector might be destroyed while we still need it.
    78   static std::vector<intptr_t> *DebugFileIDs = new std::vector<intptr_t>();
    79   return DebugFileIDs;
    80 }
    82 } // anonymous namespace
    84 namespace mozilla{
    86 // Auxiliary Method to test if a file descriptor is registered to be ignored
    87 // by the poisoning IO interposer
    88 bool IsDebugFile(intptr_t aFileID) {
    89   DebugFilesAutoLock lockedScope;
    91   std::vector<intptr_t> &Vec = *getDebugFileIDs();
    92   return std::find(Vec.begin(), Vec.end(), aFileID) != Vec.end();
    93 }
    95 // Clean-up for the registered debug files.
    96 // We should probably make sure all debug files are unregistered instead.
    97 // But as the poison IO interposer is used for late-write checks we're not
    98 // disabling it at any point yet. So Really no need for this.
    99 //
   100 // void ClearDebugFileRegister() {
   101 //   PRLock *Lock;
   102 //   {
   103 //     DebugFilesAutoLock lockedScope;
   104 //     delete getDebugFileIDs();
   105 //     Lock = DebugFilesAutoLock::getDebugFileIDsLock();
   106 //     DebugFilesAutoLock::Clear();
   107 //   }
   108 //   PR_DestroyLock(Lock);
   109 // }
   111 } // namespace mozilla
   113 extern "C" {
   115   void MozillaRegisterDebugFD(int fd) {
   116     intptr_t fileId = FileDescriptorToID(fd);
   117     DebugFilesAutoLock lockedScope;
   118     std::vector<intptr_t> &Vec = *getDebugFileIDs();
   119     MOZ_ASSERT(std::find(Vec.begin(), Vec.end(), fileId) == Vec.end());
   120     Vec.push_back(fileId);
   121   }
   123   void MozillaRegisterDebugFILE(FILE *f) {
   124     int fd = fileno(f);
   125     if (fd == 1 || fd == 2) {
   126       return;
   127     }
   128     MozillaRegisterDebugFD(fd);
   129   }
   131   void MozillaUnRegisterDebugFD(int fd) {
   132     DebugFilesAutoLock lockedScope;
   133     intptr_t fileId = FileDescriptorToID(fd);
   134     std::vector<intptr_t> &Vec = *getDebugFileIDs();
   135     std::vector<intptr_t>::iterator i =
   136       std::find(Vec.begin(), Vec.end(), fileId);
   137     MOZ_ASSERT(i != Vec.end());
   138     Vec.erase(i);
   139   }
   141   void MozillaUnRegisterDebugFILE(FILE *f) {
   142     int fd = fileno(f);
   143     if (fd == 1 || fd == 2) {
   144       return;
   145     }
   146     fflush(f);
   147     MozillaUnRegisterDebugFD(fd);
   148   }
   150 }

mercurial