Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_device/linux/latebindingsymboltable_linux.h @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

File size: 6.5 KB
Line 
1/*
2 * libjingle
3 * Copyright 2004--2010, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 *  3. The name of the author may not be used to endorse or promote products
14 *     derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef WEBRTC_AUDIO_DEVICE_LATEBINDINGSYMBOLTABLE_LINUX_H
29#define WEBRTC_AUDIO_DEVICE_LATEBINDINGSYMBOLTABLE_LINUX_H
30
31#include <assert.h>
32#include <stddef.h>  // for NULL
33#include <string.h>
34
35#include "webrtc/system_wrappers/interface/constructor_magic.h"
36#include "webrtc/system_wrappers/interface/trace.h"
37
38// This file provides macros for creating "symbol table" classes to simplify the
39// dynamic loading of symbols from DLLs. Currently the implementation only
40// supports Linux and pure C symbols.
41// See talk/sound/pulseaudiosymboltable.(h|cc) for an example.
42
43namespace webrtc_adm_linux {
44
45#ifdef WEBRTC_LINUX
46typedef void *DllHandle;
47
48const DllHandle kInvalidDllHandle = NULL;
49#else
50#error Not implemented
51#endif
52
53// These are helpers for use only by the class below.
54DllHandle InternalLoadDll(const char dll_name[]);
55
56void InternalUnloadDll(DllHandle handle);
57
58bool InternalLoadSymbols(DllHandle handle,
59                         int num_symbols,
60                         const char *const symbol_names[],
61                         void *symbols[]);
62
63template <int SYMBOL_TABLE_SIZE,
64          const char kDllName[],
65          const char *const kSymbolNames[]>
66class LateBindingSymbolTable {
67 public:
68  LateBindingSymbolTable()
69      : handle_(kInvalidDllHandle),
70        undefined_symbols_(false) {
71    memset(symbols_, 0, sizeof(symbols_));
72  }
73
74  ~LateBindingSymbolTable() {
75    Unload();
76  }
77
78  static int NumSymbols() {
79    return SYMBOL_TABLE_SIZE;
80  }
81
82  // We do not use this, but we offer it for theoretical convenience.
83  static const char *GetSymbolName(int index) {
84    assert(index < NumSymbols());
85    return kSymbolNames[index];
86  }
87
88  bool IsLoaded() const {
89    return handle_ != kInvalidDllHandle;
90  }
91
92  // Loads the DLL and the symbol table. Returns true iff the DLL and symbol
93  // table loaded successfully.
94  bool Load() {
95    if (IsLoaded()) {
96      return true;
97    }
98    if (undefined_symbols_) {
99      // We do not attempt to load again because repeated attempts are not
100      // likely to succeed and DLL loading is costly.
101      //WEBRTC_TRACE(kTraceError, kTraceAudioDevice, -1,
102      //           "We know there are undefined symbols");
103      return false;
104    }
105    handle_ = InternalLoadDll(kDllName);
106    if (!IsLoaded()) {
107      return false;
108    }
109    if (!InternalLoadSymbols(handle_, NumSymbols(), kSymbolNames, symbols_)) {
110      undefined_symbols_ = true;
111      Unload();
112      return false;
113    }
114    return true;
115  }
116
117  void Unload() {
118    if (!IsLoaded()) {
119      return;
120    }
121    InternalUnloadDll(handle_);
122    handle_ = kInvalidDllHandle;
123    memset(symbols_, 0, sizeof(symbols_));
124  }
125
126  // Retrieves the given symbol. NOTE: Recommended to use LATESYM_GET below
127  // instead of this.
128  void *GetSymbol(int index) const {
129    assert(IsLoaded());
130    assert(index < NumSymbols());
131    return symbols_[index];
132  }
133
134 private:
135  DllHandle handle_;
136  bool undefined_symbols_;
137  void *symbols_[SYMBOL_TABLE_SIZE];
138
139  DISALLOW_COPY_AND_ASSIGN(LateBindingSymbolTable);
140};
141
142// This macro must be invoked in a header to declare a symbol table class.
143#define LATE_BINDING_SYMBOL_TABLE_DECLARE_BEGIN(ClassName) \
144enum {
145
146// This macro must be invoked in the header declaration once for each symbol
147// (recommended to use an X-Macro to avoid duplication).
148// This macro defines an enum with names built from the symbols, which
149// essentially creates a hash table in the compiler from symbol names to their
150// indices in the symbol table class.
151#define LATE_BINDING_SYMBOL_TABLE_DECLARE_ENTRY(ClassName, sym) \
152  ClassName##_SYMBOL_TABLE_INDEX_##sym,
153
154// This macro completes the header declaration.
155#define LATE_BINDING_SYMBOL_TABLE_DECLARE_END(ClassName) \
156  ClassName##_SYMBOL_TABLE_SIZE \
157}; \
158\
159extern const char ClassName##_kDllName[]; \
160extern const char *const \
161    ClassName##_kSymbolNames[ClassName##_SYMBOL_TABLE_SIZE]; \
162\
163typedef ::webrtc_adm_linux::LateBindingSymbolTable<ClassName##_SYMBOL_TABLE_SIZE, \
164                                            ClassName##_kDllName, \
165                                            ClassName##_kSymbolNames> \
166    ClassName;
167
168// This macro must be invoked in a .cc file to define a previously-declared
169// symbol table class.
170#define LATE_BINDING_SYMBOL_TABLE_DEFINE_BEGIN(ClassName, dllName) \
171const char ClassName##_kDllName[] = dllName; \
172const char *const ClassName##_kSymbolNames[ClassName##_SYMBOL_TABLE_SIZE] = {
173
174// This macro must be invoked in the .cc definition once for each symbol
175// (recommended to use an X-Macro to avoid duplication).
176// This would have to use the mangled name if we were to ever support C++
177// symbols.
178#define LATE_BINDING_SYMBOL_TABLE_DEFINE_ENTRY(ClassName, sym) \
179  #sym,
180
181#define LATE_BINDING_SYMBOL_TABLE_DEFINE_END(ClassName) \
182};
183
184// Index of a given symbol in the given symbol table class.
185#define LATESYM_INDEXOF(ClassName, sym) \
186  (ClassName##_SYMBOL_TABLE_INDEX_##sym)
187
188// Returns a reference to the given late-binded symbol, with the correct type.
189#define LATESYM_GET(ClassName, inst, sym) \
190  (*reinterpret_cast<typeof(&sym)>( \
191      (inst)->GetSymbol(LATESYM_INDEXOF(ClassName, sym))))
192
193}  // namespace webrtc_adm_linux
194
195#endif  // WEBRTC_ADM_LATEBINDINGSYMBOLTABLE_LINUX_H
Note: See TracBrowser for help on using the repository browser.