Compare commits

...

5 Commits

Author SHA1 Message Date
Slava Monich
c22eafe49e Version 1.1.25 2022-07-19 02:04:30 +03:00
Slava Monich
66122a2ce6 [unit] Added unit test for device + protocol combo. JB#42254 2022-07-19 02:01:26 +03:00
Slava Monich
c1ff25f6ae [gbinder] Housekeeping. JB#42254 2022-07-19 01:57:13 +03:00
Slava Monich
af3c23a18f Merge pull request #98 from aleasto/master
Handle changing the rpc protocol during execution
2022-07-19 01:49:19 +03:00
Alessandro Astone
5a14796c4c [gbinder] Handle changing the rpc protocol during execution
When calling gbinder_ipc_new with a different protocol for the same
device node, we would end up getting the old cached GBinderIpc object
referencing the old protocol.

Make the hash table key uniquely identify a (dev,protocol) pair.
2022-07-19 00:47:51 +02:00
5 changed files with 66 additions and 20 deletions

View File

@@ -16,7 +16,7 @@
VERSION_MAJOR = 1
VERSION_MINOR = 1
VERSION_RELEASE = 24
VERSION_RELEASE = 25
# Version for pkg-config
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)

6
debian/changelog vendored
View File

@@ -1,3 +1,9 @@
libgbinder (1.1.25) unstable; urgency=low
* Handle RPC protocol change at run time
-- Slava Monich <slava.monich@jolla.com> Tue, 19 Jul 2022 02:02:41 +0300
libgbinder (1.1.24) unstable; urgency=low
* Bumped debhelper compat level to 7

View File

@@ -1,6 +1,6 @@
Name: libgbinder
Version: 1.1.24
Version: 1.1.25
Release: 0
Summary: Binder client library
License: BSD

View File

@@ -64,6 +64,7 @@ struct gbinder_ipc_priv {
GBinderIpc* self;
GThreadPool* tx_pool;
GHashTable* tx_table;
char* dev;
char* key;
const char* name;
GBinderObjectRegistry object_registry;
@@ -265,6 +266,15 @@ gbinder_ipc_wait(
return FALSE;
}
static
char*
gbinder_ipc_make_key(
const char* dev,
const char* protocol)
{
return g_strdup_printf("%s:%s", protocol, dev);
}
/*==========================================================================*
* GBinderIpcLooperTx
*==========================================================================*/
@@ -1847,18 +1857,21 @@ gbinder_ipc_new(
const char* protocol_name)
{
GBinderIpc* self = NULL;
char* key;
const GBinderRpcProtocol* protocol = (protocol_name ?
gbinder_rpc_protocol_by_name(protocol_name) : NULL);
if (!dev || !dev[0]) dev = GBINDER_DEFAULT_BINDER;
if (!protocol) protocol = gbinder_rpc_protocol_for_device(dev);
key = gbinder_ipc_make_key(dev, protocol->name);
/* Lock */
pthread_mutex_lock(&gbinder_ipc_mutex);
if (gbinder_ipc_table) {
self = g_hash_table_lookup(gbinder_ipc_table, dev);
self = g_hash_table_lookup(gbinder_ipc_table, key);
}
if (self) {
g_free(key);
gbinder_ipc_ref(self);
} else {
GBinderDriver* driver = gbinder_driver_new(dev, protocol);
@@ -1869,7 +1882,8 @@ gbinder_ipc_new(
self = g_object_new(THIS_TYPE, NULL);
priv = self->priv;
self->driver = driver;
self->dev = priv->key = g_strdup(dev);
self->dev = priv->dev = g_strdup(dev);
priv->key = key;
self->priv->object_registry.io = gbinder_driver_io(driver);
/* gbinder_ipc_dispose will remove iself from the table */
if (!gbinder_ipc_table) {
@@ -1877,8 +1891,10 @@ gbinder_ipc_new(
}
g_hash_table_replace(gbinder_ipc_table, priv->key, self);
/* With "/dev/" prefix, it may be too long to be a thread name */
priv->name = priv->key +
(g_str_has_prefix(priv->key, "/dev/") ? 5 : 0);
priv->name = self->dev +
(g_str_has_prefix(priv->dev, "/dev/") ? 5 : 0);
} else {
g_free(key);
}
}
pthread_mutex_unlock(&gbinder_ipc_mutex);
@@ -2138,6 +2154,7 @@ gbinder_ipc_finalize(
GASSERT(!g_hash_table_size(priv->tx_table));
g_hash_table_unref(priv->tx_table);
gbinder_driver_unref(self->driver);
g_free(priv->dev);
g_free(priv->key);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}

View File

@@ -79,26 +79,25 @@ void
test_null(
void)
{
GBinderIpc* null = NULL;
int status = INT_MAX;
g_assert(!gbinder_ipc_ref(null));
gbinder_ipc_unref(null);
g_assert(!gbinder_ipc_sync_main.sync_reply(null, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_main.sync_reply(null, 0, 0, NULL, &status));
g_assert(!gbinder_ipc_ref(NULL));
gbinder_ipc_unref(NULL);
g_assert(!gbinder_ipc_sync_main.sync_reply(NULL, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_main.sync_reply(NULL, 0, 0, NULL, &status));
g_assert_cmpint(status, == ,-EINVAL);
g_assert(!gbinder_ipc_sync_worker.sync_reply(null, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_worker.sync_reply(null, 0, 0, NULL, &status));
g_assert(!gbinder_ipc_sync_worker.sync_reply(NULL, 0, 0, NULL, NULL));
g_assert(!gbinder_ipc_sync_worker.sync_reply(NULL, 0, 0, NULL, &status));
g_assert_cmpint(status, == ,-EINVAL);
g_assert_cmpint(gbinder_ipc_sync_main.sync_oneway(null, 0, 0, NULL), == ,
g_assert_cmpint(gbinder_ipc_sync_main.sync_oneway(NULL, 0, 0, NULL), == ,
-EINVAL);
g_assert_cmpint(gbinder_ipc_sync_worker.sync_oneway(null, 0, 0, NULL), == ,
g_assert_cmpint(gbinder_ipc_sync_worker.sync_oneway(NULL, 0, 0, NULL), == ,
-EINVAL);
g_assert(!gbinder_ipc_transact(null, 0, 0, 0, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_transact_custom(null, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_object_registry(null));
gbinder_ipc_looper_check(null);
gbinder_ipc_cancel(null, 0);
g_assert(!gbinder_ipc_transact(NULL, 0, 0, 0, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_transact_custom(NULL, NULL, NULL, NULL, NULL));
g_assert(!gbinder_ipc_object_registry(NULL));
gbinder_ipc_looper_check(NULL);
gbinder_ipc_cancel(NULL, 0);
g_assert(!gbinder_object_registry_ref(NULL));
gbinder_object_registry_unref(NULL);
@@ -167,6 +166,29 @@ test_basic(
test_binder_exit_wait(&test_opt, NULL);
}
/*==========================================================================*
* protocol
*==========================================================================*/
static
void
test_protocol(
void)
{
/* GBinderIpc objects are identified by device + protocol combination */
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, "aidl");
GBinderIpc* ipc2 = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, "hidl");
g_assert(ipc);
g_assert(ipc2);
g_assert(ipc != ipc2);
gbinder_ipc_unref(ipc);
gbinder_ipc_unref(ipc2);
gbinder_ipc_exit();
test_binder_exit_wait(&test_opt, NULL);
}
/*==========================================================================*
* async_oneway
*==========================================================================*/
@@ -1350,6 +1372,7 @@ int main(int argc, char* argv[])
g_test_init(&argc, &argv, NULL);
g_test_add_func(TEST_("null"), test_null);
g_test_add_func(TEST_("basic"), test_basic);
g_test_add_func(TEST_("protocol"), test_protocol);
g_test_add_func(TEST_("async_oneway"), test_async_oneway);
g_test_add_func(TEST_("sync_oneway"), test_sync_oneway);
g_test_add_func(TEST_("sync_reply_ok"), test_sync_reply_ok);