Reputation: 1
Language: C++/C Android Makefile System: https://developer.android.com/ndk/guides/android_mk
I have an application which open a shared library foo.so
and within foo.so we open three other shared libraries bar1.so
, bar2.so
and bar3.so
in three different threads (pthread_create) but in same application/process.
pid is same, thread id is different for bar1, bar2, bar3
Each of bar1.so
, bar2.so
, bar3.so
have Entry
functions which are called using dlsym
after dlopen
and different types of objects are created within bar1 2 3.so
libs
bar1.so
, bar2.so
and bar3.so
also have dynamic linking to another shared library called baz.so
which has some common structs/routines. baz.so
Not explicitly 'dlopen' ed. In make files of bar1.so, bar2.so, bar3.so I specify baz.so
as a shared library which it needs. I want to create a singleton structure in baz.so
where each of bar1.so
, bar2.so
and bar3.so
can write and read to/from.
I tried creating a static object in baz.so
but bar1.so
, bar2.so
and bar3.so
seems to get their distinct copies of the structure. Its not shared.
By Distinct copies i mean that according to code snippet below, when I read in bar2.so , sharedData.a
is 10 and not 22
baz.so:
Filename: sharedobject.h -> All code is defined in sharedobject.h file in baz.so
struct Config {
int a;
bool b;
// Constructor
Config (int val1, bool val2) {
a = val1;
b = val2;
}
};
class SharedObject {
public:
Config sharedData;
SharedObject() {
// Initialize some common data here which will be read
// and written to
sharedData.a = 10;
sharedData.b = 20;
}
static SharedObject* GetInstance() {
static SharedObject singletonObjectInstance;
return &singletonObjectInstance;
}
// Data update function called by either of bar1, bar2 or bar3.so
static void UpdateData(Config &data) {
// Lock : Proper Locking is there but not shown in code
SharedObject::GetInstance()->sharedData.a = data.a;
// Unlock
}
}
Android.mk:
LOCAL_SRC_FILES := // Empty fields
LOCAL_INC_FILES := // Empty Fields
LOCAL_MODULE := baz
include $(BUILD_SHARED_LIBRARY) # This will build baz.so
bar1.so: Let's say Thread1 under ProcessX updates some data
Filename: classx.cpp
#include "sharedobject.h"
void ClassX::WriteToCommonData() {
SharedObject *pSharedObject= SharedObject::GetInstance();
print("Object Address:%p", pSharedObject); // These addresses are not same in bar1 and bar2 which is the problem
Config data(22, false);
SharedObject::UpdateData(data);
}
In Android.mk of bar1.so
Linking is done by specifying shared lib: -> https://developer.android.com/ndk/guides/android_mk#local_shared_libraries
LOCAL_SRC_FILES := classx.cpp
LOCAL_SHARED_LIBRARIES := baz.so
LOCAL_CFLAGS := # No Special flags used.
LOCAL_MODULE := bar1
include $(BUILD_SHARED_LIBRARY) # This will build bar1.so
bar2.so: Lets's say Thread2 under same ProcessX wants to read it now
Filename: classy.cpp
#include "sharedobject.h"
void ClassY::ReadFromCommonData() {
SharedObject *pSharedObject= SharedObject::GetInstance();
print("Object Address:%p", pSharedObject); // These addresses are not same in bar1 and bar2 which is the problem
// Read values updated by bar1.so
print(pSharedObject->sharedData.a); // It is 10, not 22
}
In Android.mk
LOCAL_SHARED_LIBRARIES := baz.so
LOCAL_SRC_FILES := classy.cpp
LOCAL_CFLAGS := # No Special flags used.
LOCAL_MODULE := bar2
include $(BUILD_SHARED_LIBRARY) # This will build bar2.so
Even though all bar libraries are under same Process, do I still need to use Shared memory APIs ?
I have checked these links but it does not seem to answer my question: how to share a single shared library(*.so) instance between two applications Shared Library Structure
Upvotes: 0
Views: 531
Reputation: 1
class __attribute__ ((visibility ("default")) SharedObject
Defining the class as above solved the issue. It seems like without this, symbol is not exported and not available for dynamic linker.
Upvotes: 0
Reputation: 238291
What you need is synchronisation. Your UpdateData
has "lock" and "unlock", which I presume are placeholders for thread synchronisation. At least, they should be. But your example doesn't lock when reading the variable. Both reader and the writer need to lock. Besides locking to ensure race-free access, you need to use some mechanism to ensure that the read happens after the write and not before. For example, a condition variable could be used.
Upvotes: 0