Skip to content

Commit

Permalink
Linux DSO loading always had been very peculiar due to macro magic.
Browse files Browse the repository at this point in the history
At least now it is peculiar shared magic with only one implementation.
  • Loading branch information
Nicky-D committed Apr 7, 2024
1 parent cc642b7 commit 5b39ee2
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 509 deletions.
56 changes: 56 additions & 0 deletions indra/media_plugins/base/media_plugin_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,62 @@ void MediaPluginBase::sendStatus()
sendMessage(message);
}

#if LL_LINUX
namespace {
std::vector< SymbolToGrab > gSymbolsToGrab;
}
bool registerSymbol( SymbolToGrab aSymbol )
{
gSymbolsToGrab.emplace_back(aSymbol);
return true;
}

bool SymbolGrabber::sSymsGrabbed;
apr_pool_t *SymbolGrabber::sSymPADSOMemoryPool;
std::vector<apr_dso_handle_t *> SymbolGrabber::sLoadedLibraries;

bool SymbolGrabber::grabSymbols(std::vector< std::string > const &aDSONames)
{
if (sSymsGrabbed)
return true;

//attempt to load the shared libraries
apr_pool_create(&sSymPADSOMemoryPool, nullptr);

for( std::vector< std::string >::const_iterator itr = aDSONames.begin(); itr != aDSONames.end(); ++itr )
{
apr_dso_handle_t *pDSO(NULL);
std::string strDSO{ *itr };
if( APR_SUCCESS == apr_dso_load( &pDSO, strDSO.c_str(), sSymPADSOMemoryPool ))
sLoadedLibraries.push_back( pDSO );


for( auto i = 0; i < gSymbolsToGrab.size(); ++i )
{
if( !*gSymbolsToGrab[i].mPPFunc )
apr_dso_sym( gSymbolsToGrab[i].mPPFunc, pDSO, gSymbolsToGrab[i].mName );
}
}

bool sym_error = false;

for( auto i = 0; i < gSymbolsToGrab.size(); ++i )
{
if( gSymbolsToGrab[ i ].mRequired && ! *gSymbolsToGrab[ i ].mPPFunc )
sym_error = true;
}


sSymsGrabbed = !sym_error;
return sSymsGrabbed;
}

void SymbolGrabber::ungrabSymbols()
{

}
#endif


#if LL_WINDOWS
# define LLSYMEXPORT __declspec(dllexport)
Expand Down
24 changes: 23 additions & 1 deletion indra/media_plugins/base/media_plugin_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,29 @@
#include "llpluginmessage.h"
#include "llpluginmessageclasses.h"

#if LL_LINUX
class SymbolGrabber
{
protected:
static bool grabSymbols(std::vector< std::string > const &aDSONames);
static void ungrabSymbols();
private:
static bool sSymsGrabbed;
static apr_pool_t *sSymPADSOMemoryPool;
static std::vector<apr_dso_handle_t *> sLoadedLibraries;
};

struct SymbolToGrab
{
bool mRequired;
char const *mName;
apr_dso_handle_sym_t *mPPFunc;
};

extern bool registerSymbol( SymbolToGrab aSymbol );
#define LL_GRAB_SYM(REQUIRED, SYMBOL_NAME, RETURN, ...) RETURN (*ll##SYMBOL_NAME)(__VA_ARGS__) = nullptr; bool gRegistered##SYMBOL_NAME = registerSymbol( { REQUIRED, #SYMBOL_NAME , (apr_dso_handle_sym_t*)&ll##SYMBOL_NAME} );

#endif

class MediaPluginBase
{
Expand All @@ -46,7 +69,6 @@ class MediaPluginBase
static void staticReceiveMessage(const char *message_string, void **user_data);

protected:

/** Plugin status. */
typedef enum
{
Expand Down
123 changes: 17 additions & 106 deletions indra/media_plugins/cef/linux_volume_catcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include "volume_catcher.h"
#include <set>
#include <map>

#include <iostream>
extern "C" {
#include <glib.h>
#include <glib-object.h>
Expand All @@ -54,99 +54,11 @@ extern "C" {
#include "apr_dso.h"
}

#include "media_plugin_base.h"

////////////////////////////////////////////////////

#define DEBUGMSG(...) do {} while(0)
#define INFOMSG(...) do {} while(0)
#define WARNMSG(...) do {} while(0)

#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) RTN (*ll##PASYM)(__VA_ARGS__) = NULL
#include "linux_volume_catcher_pa_syms.inc"
#include "linux_volume_catcher_paglib_syms.inc"
#undef LL_PA_SYM

static bool sSymsGrabbed = false;
static apr_pool_t *sSymPADSOMemoryPool = NULL;
static apr_dso_handle_t *sSymPADSOHandleG = NULL;

bool grab_pa_syms(std::string pulse_dso_name)
{
if (sSymsGrabbed)
{
// already have grabbed good syms
return true;
}

bool sym_error = false;
bool rtn = false;
apr_status_t rv;
apr_dso_handle_t *sSymPADSOHandle = NULL;

#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) { if (REQUIRED) sym_error = true;} } while(0);

//attempt to load the shared library
apr_pool_create(&sSymPADSOMemoryPool, NULL);

if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle,
pulse_dso_name.c_str(),
sSymPADSOMemoryPool) ))
{
INFOMSG("Found DSO: %s", pulse_dso_name.c_str());

#include "linux_volume_catcher_pa_syms.inc"
#include "linux_volume_catcher_paglib_syms.inc"

if ( sSymPADSOHandle )
{
sSymPADSOHandleG = sSymPADSOHandle;
sSymPADSOHandle = NULL;
}

rtn = !sym_error;
}
else
{
INFOMSG("Couldn't load DSO: %s", pulse_dso_name.c_str());
rtn = false; // failure
}

if (sym_error)
{
WARNMSG("Failed to find necessary symbols in PulseAudio libraries.");
}
#undef LL_PA_SYM

sSymsGrabbed = rtn;
return rtn;
}


void ungrab_pa_syms()
{
// should be safe to call regardless of whether we've
// actually grabbed syms.

if ( sSymPADSOHandleG )
{
apr_dso_unload(sSymPADSOHandleG);
sSymPADSOHandleG = NULL;
}

if ( sSymPADSOMemoryPool )
{
apr_pool_destroy(sSymPADSOMemoryPool);
sSymPADSOMemoryPool = NULL;
}

// NULL-out all of the symbols we'd grabbed
#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0)
#include "linux_volume_catcher_pa_syms.inc"
#include "linux_volume_catcher_paglib_syms.inc"
#undef LL_PA_SYM

sSymsGrabbed = false;
}
////////////////////////////////////////////////////

// PulseAudio requires a chain of callbacks with C linkage
Expand All @@ -157,7 +69,7 @@ extern "C" {
}


class VolumeCatcherImpl
class VolumeCatcherImpl: SymbolGrabber
{
public:
VolumeCatcherImpl();
Expand Down Expand Up @@ -187,8 +99,8 @@ class VolumeCatcherImpl

VolumeCatcherImpl::VolumeCatcherImpl()
: mDesiredVolume(0.0f),
mMainloop(NULL),
mPAContext(NULL),
mMainloop(nullptr),
mPAContext(nullptr),
mConnected(false),
mGotSyms(false)
{
Expand All @@ -202,7 +114,8 @@ VolumeCatcherImpl::~VolumeCatcherImpl()

bool VolumeCatcherImpl::loadsyms(std::string pulse_dso_name)
{
return grab_pa_syms(pulse_dso_name);
//return grab_pa_syms({pulse_dso_name});
return SymbolGrabber::grabSymbols( { pulse_dso_name }) ;
}

void VolumeCatcherImpl::init()
Expand Down Expand Up @@ -236,7 +149,7 @@ void VolumeCatcherImpl::init()
llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");

// plain old pa_context_new() is broken!
mPAContext = llpa_context_new_with_proplist(api, NULL, proplist);
mPAContext = llpa_context_new_with_proplist(api, nullptr, proplist);

llpa_proplist_free(proplist);
}
Expand All @@ -249,7 +162,7 @@ void VolumeCatcherImpl::init()
{
llpa_context_set_state_callback(mPAContext, callback_context_state, this);
pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
if (llpa_context_connect(mPAContext, NULL, cflags, NULL) >= 0)
if (llpa_context_connect(mPAContext, nullptr, cflags, nullptr) >= 0)
{
// Okay! We haven't definitely connected, but we
// haven't definitely failed yet.
Expand All @@ -271,13 +184,13 @@ void VolumeCatcherImpl::cleanup()
llpa_context_disconnect(mPAContext);
llpa_context_unref(mPAContext);
}
mPAContext = NULL;

mPAContext = nullptr;

if (mGotSyms && mMainloop)
{
llpa_glib_mainloop_free(mMainloop);
}
mMainloop = NULL;

mMainloop = nullptr;
}

void VolumeCatcherImpl::setVolume(F32 volume)
Expand Down Expand Up @@ -318,7 +231,7 @@ void VolumeCatcherImpl::connected_okay()
this);
if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
(PA_SUBSCRIPTION_MASK_SINK_INPUT),
NULL, NULL)))
nullptr, nullptr)))
{
llpa_operation_unref(op);
}
Expand All @@ -342,14 +255,12 @@ void VolumeCatcherImpl::update_index_volume(U32 index, F32 volume)
pa_context *c = mPAContext;
uint32_t idx = index;
const pa_cvolume *cvolumep = &cvol;
pa_context_success_cb_t cb = NULL; // okay as null
void *userdata = NULL; // okay as null
pa_context_success_cb_t cb = nullptr; // okay as null
void *userdata = nullptr; // okay as null

pa_operation *op;
if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
{
llpa_operation_unref(op);
}
}

pid_t getParentPid( pid_t aPid )
Expand Down Expand Up @@ -492,7 +403,7 @@ VolumeCatcher::VolumeCatcher()
VolumeCatcher::~VolumeCatcher()
{
delete pimpl;
pimpl = NULL;
pimpl = nullptr;
}

void VolumeCatcher::setVolume(F32 volume)
Expand Down
36 changes: 18 additions & 18 deletions indra/media_plugins/cef/linux_volume_catcher_pa_syms.inc
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// required symbols to grab
LL_PA_SYM(true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api);
LL_PA_SYM(true, pa_context_disconnect, void, pa_context *c);
LL_PA_SYM(true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata);
LL_PA_SYM(true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata);
LL_PA_SYM(true, pa_context_get_state, pa_context_state_t, pa_context *c);
LL_PA_SYM(true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist);
LL_PA_SYM(true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata);
LL_PA_SYM(true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata);
LL_PA_SYM(true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata);
LL_PA_SYM(true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata);
LL_PA_SYM(true, pa_context_unref, void, pa_context *c);
LL_PA_SYM(true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v);
LL_PA_SYM(true, pa_operation_unref, void, pa_operation *o);
LL_PA_SYM(true, pa_proplist_free, void, pa_proplist* p);
LL_PA_SYM(true, pa_proplist_gets, const char*, pa_proplist *p, const char *key);
LL_PA_SYM(true, pa_proplist_new, pa_proplist*, void);
LL_PA_SYM(true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value);
LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v);
LL_GRAB_SYM(true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api)
LL_GRAB_SYM(true, pa_context_disconnect, void, pa_context *c)
LL_GRAB_SYM(true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata)
LL_GRAB_SYM(true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata)
LL_GRAB_SYM(true, pa_context_get_state, pa_context_state_t, pa_context *c)
LL_GRAB_SYM(true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist)
LL_GRAB_SYM(true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata)
LL_GRAB_SYM(true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata)
LL_GRAB_SYM(true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata)
LL_GRAB_SYM(true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata)
LL_GRAB_SYM(true, pa_context_unref, void, pa_context *c)
LL_GRAB_SYM(true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v)
LL_GRAB_SYM(true, pa_operation_unref, void, pa_operation *o)
LL_GRAB_SYM(true, pa_proplist_free, void, pa_proplist* p)
LL_GRAB_SYM(true, pa_proplist_gets, const char*, pa_proplist *p, const char *key)
LL_GRAB_SYM(true, pa_proplist_new, pa_proplist*, void)
LL_GRAB_SYM(true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value)
LL_GRAB_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v)

// optional symbols to grab
6 changes: 3 additions & 3 deletions indra/media_plugins/cef/linux_volume_catcher_paglib_syms.inc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// required symbols to grab
LL_PA_SYM(true, pa_glib_mainloop_free, void, pa_glib_mainloop* g);
LL_PA_SYM(true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g);
LL_PA_SYM(true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c);
LL_GRAB_SYM(true, pa_glib_mainloop_free, void, pa_glib_mainloop* g)
LL_GRAB_SYM(true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g)
LL_GRAB_SYM(true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c)

// optional symbols to grab
1 change: 0 additions & 1 deletion indra/media_plugins/gstreamer10/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ endif()

set(media_plugin_gstreamer10_SOURCE_FILES
media_plugin_gstreamer10.cpp
llmediaimplgstreamer_syms.cpp
)

set(media_plugin_gstreamer10_HEADER_FILES
Expand Down
Loading

0 comments on commit 5b39ee2

Please sign in to comment.