LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_device/linux - latebindingsymboltable_linux.h (source / functions) Hit Total Coverage
Test: output.info Lines: 4 34 11.8 %
Date: 2017-07-14 16:53:18 Functions: 1 7 14.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2010 The WebRTC 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             : 
      11             : #ifndef WEBRTC_AUDIO_DEVICE_LATEBINDINGSYMBOLTABLE_LINUX_H
      12             : #define WEBRTC_AUDIO_DEVICE_LATEBINDINGSYMBOLTABLE_LINUX_H
      13             : 
      14             : #include <assert.h>
      15             : #include <stddef.h>  // for NULL
      16             : #include <string.h>
      17             : 
      18             : #include "webrtc/base/constructormagic.h"
      19             : #include "webrtc/system_wrappers/include/trace.h"
      20             : 
      21             : // This file provides macros for creating "symbol table" classes to simplify the
      22             : // dynamic loading of symbols from DLLs. Currently the implementation only
      23             : // supports Linux and pure C symbols.
      24             : // See talk/sound/pulseaudiosymboltable.(h|cc) for an example.
      25             : 
      26             : namespace webrtc_adm_linux {
      27             : 
      28             : #if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD)
      29             : typedef void *DllHandle;
      30             : 
      31             : const DllHandle kInvalidDllHandle = NULL;
      32             : #else
      33             : #error Not implemented
      34             : #endif
      35             : 
      36             : // These are helpers for use only by the class below.
      37             : DllHandle InternalLoadDll(const char dll_name[]);
      38             : 
      39             : void InternalUnloadDll(DllHandle handle);
      40             : 
      41             : bool InternalLoadSymbols(DllHandle handle,
      42             :                          int num_symbols,
      43             :                          const char *const symbol_names[],
      44             :                          void *symbols[]);
      45             : 
      46             : template <int SYMBOL_TABLE_SIZE,
      47             :           const char kDllName[],
      48             :           const char *const kSymbolNames[]>
      49             : class LateBindingSymbolTable {
      50             :  public:
      51           3 :   LateBindingSymbolTable()
      52             :       : handle_(kInvalidDllHandle),
      53           3 :         undefined_symbols_(false) {
      54           3 :     memset(symbols_, 0, sizeof(symbols_));
      55           3 :   }
      56             : 
      57           0 :   ~LateBindingSymbolTable() {
      58           0 :     Unload();
      59           0 :   }
      60             : 
      61           0 :   static int NumSymbols() {
      62           0 :     return SYMBOL_TABLE_SIZE;
      63             :   }
      64             : 
      65             :   // We do not use this, but we offer it for theoretical convenience.
      66             :   static const char *GetSymbolName(int index) {
      67             :     assert(index < NumSymbols());
      68             :     return kSymbolNames[index];
      69             :   }
      70             : 
      71           0 :   bool IsLoaded() const {
      72           0 :     return handle_ != kInvalidDllHandle;
      73             :   }
      74             : 
      75             :   // Loads the DLL and the symbol table. Returns true iff the DLL and symbol
      76             :   // table loaded successfully.
      77           0 :   bool Load() {
      78           0 :     if (IsLoaded()) {
      79           0 :       return true;
      80             :     }
      81           0 :     if (undefined_symbols_) {
      82             :       // We do not attempt to load again because repeated attempts are not
      83             :       // likely to succeed and DLL loading is costly.
      84             :       //WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
      85             :       //           "We know there are undefined symbols");
      86           0 :       return false;
      87             :     }
      88           0 :     handle_ = InternalLoadDll(kDllName);
      89           0 :     if (!IsLoaded()) {
      90           0 :       return false;
      91             :     }
      92           0 :     if (!InternalLoadSymbols(handle_, NumSymbols(), kSymbolNames, symbols_)) {
      93           0 :       undefined_symbols_ = true;
      94           0 :       Unload();
      95           0 :       return false;
      96             :     }
      97           0 :     return true;
      98             :   }
      99             : 
     100           0 :   void Unload() {
     101           0 :     if (!IsLoaded()) {
     102           0 :       return;
     103             :     }
     104           0 :     InternalUnloadDll(handle_);
     105           0 :     handle_ = kInvalidDllHandle;
     106           0 :     memset(symbols_, 0, sizeof(symbols_));
     107             :   }
     108             : 
     109             :   // Retrieves the given symbol. NOTE: Recommended to use LATESYM_GET below
     110             :   // instead of this.
     111           0 :   void *GetSymbol(int index) const {
     112           0 :     assert(IsLoaded());
     113           0 :     assert(index < NumSymbols());
     114           0 :     return symbols_[index];
     115             :   }
     116             : 
     117             :  private:
     118             :   DllHandle handle_;
     119             :   bool undefined_symbols_;
     120             :   void *symbols_[SYMBOL_TABLE_SIZE];
     121             : 
     122             :   RTC_DISALLOW_COPY_AND_ASSIGN(LateBindingSymbolTable);
     123             : };
     124             : 
     125             : // This macro must be invoked in a header to declare a symbol table class.
     126             : #define LATE_BINDING_SYMBOL_TABLE_DECLARE_BEGIN(ClassName) \
     127             : enum {
     128             : 
     129             : // This macro must be invoked in the header declaration once for each symbol
     130             : // (recommended to use an X-Macro to avoid duplication).
     131             : // This macro defines an enum with names built from the symbols, which
     132             : // essentially creates a hash table in the compiler from symbol names to their
     133             : // indices in the symbol table class.
     134             : #define LATE_BINDING_SYMBOL_TABLE_DECLARE_ENTRY(ClassName, sym) \
     135             :   ClassName##_SYMBOL_TABLE_INDEX_##sym,
     136             : 
     137             : // This macro completes the header declaration.
     138             : #define LATE_BINDING_SYMBOL_TABLE_DECLARE_END(ClassName) \
     139             :   ClassName##_SYMBOL_TABLE_SIZE \
     140             : }; \
     141             : \
     142             : extern const char ClassName##_kDllName[]; \
     143             : extern const char *const \
     144             :     ClassName##_kSymbolNames[ClassName##_SYMBOL_TABLE_SIZE]; \
     145             : \
     146             : typedef ::webrtc_adm_linux::LateBindingSymbolTable<ClassName##_SYMBOL_TABLE_SIZE, \
     147             :                                             ClassName##_kDllName, \
     148             :                                             ClassName##_kSymbolNames> \
     149             :     ClassName;
     150             : 
     151             : // This macro must be invoked in a .cc file to define a previously-declared
     152             : // symbol table class.
     153             : #define LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(ClassName, dllName) \
     154             : const char ClassName##_kDllName[] = dllName; \
     155             : const char *const ClassName##_kSymbolNames[ClassName##_SYMBOL_TABLE_SIZE] = {
     156             : 
     157             : // This macro must be invoked in the .cc definition once for each symbol
     158             : // (recommended to use an X-Macro to avoid duplication).
     159             : // This would have to use the mangled name if we were to ever support C++
     160             : // symbols.
     161             : #define LATE_BINDING_SYMBOL_TABLE_DEFINE_ENTRY(ClassName, sym) \
     162             :   #sym,
     163             : 
     164             : #define LATE_BINDING_SYMBOL_TABLE_DEFINE_END(ClassName) \
     165             : };
     166             : 
     167             : // Index of a given symbol in the given symbol table class.
     168             : #define LATESYM_INDEXOF(ClassName, sym) \
     169             :   (ClassName##_SYMBOL_TABLE_INDEX_##sym)
     170             : 
     171             : // Returns a reference to the given late-binded symbol, with the correct type.
     172             : #define LATESYM_GET(ClassName, inst, sym) \
     173             :   (*reinterpret_cast<typeof(&sym)>( \
     174             :       (inst)->GetSymbol(LATESYM_INDEXOF(ClassName, sym))))
     175             : 
     176             : }  // namespace webrtc_adm_linux
     177             : 
     178             : #endif  // WEBRTC_ADM_LATEBINDINGSYMBOLTABLE_LINUX_H

Generated by: LCOV version 1.13