Compare commits

...

21 Commits

Author SHA1 Message Date
Slava Monich
5805290369 Version 1.0.43 2020-06-03 15:16:40 +03:00
Slava Monich
7dd9623929 Merge pull request #48 from krnlyng/jb49520
Allow strip command to be replaced through external environment variable STRIP
2020-06-03 15:07:57 +03:00
Slava Monich
95ac07e4de Merge pull request #49 from monich/lib64
Respect arch specific lib dir
2020-06-03 15:04:36 +03:00
Slava Monich
92cd463b34 [gbinder] Respect arch specific lib dir. JB#49681 2020-06-03 01:47:58 +03:00
Slava Monich
6832546dca [gbinder] Hide internal symbols. JB#42956 2020-06-03 01:33:23 +03:00
Franz-Josef Haider
049042b134 libgbinder: allow strip command to be replaced through external environment variable STRIP.
[libgbinder] allow strip command to be replaced through external environment variable STRIP. JB#49520
2020-05-29 12:22:40 +00:00
Slava Monich
6d2f2efe31 Version 1.0.42 2020-05-05 20:01:45 +03:00
Slava Monich
bcce4831e3 Merge pull request #47 from monich/multi-client
Support for multiple versions of hwbinder interfaces
2020-05-05 19:55:06 +03:00
Slava Monich
7fb3053135 [unit] Added test for the GBinderClient API. JB#49360 2020-05-05 19:45:36 +03:00
Slava Monich
00359a0fc8 [gbinder] Allow GBinderClient to use more than one interface. JB#49360
Or more likely, multiple versions of the same interface. For example,
first N transaction codes may be associated with version 1.0 of the
interface, the next M codes with version 1.1 and so on.

The following new functions have been introduced:

  gbinder_client_new2
  gbinder_client_interface2
  gbinder_client_new_request2

Note that a similar functionality could be achieved by allocating
a separate client for each version of the interface. This is just
a more convenient way of doing pretty much the same thing.

The old API still works, just assumes the same interface for all
transaction codes.
2020-05-05 19:44:14 +03:00
Slava Monich
ccf3e1237c Version 1.0.41 2020-04-14 12:40:05 +03:00
Slava Monich
e02f00fd41 Merge pull request #45 from monich/idle-pool
Stop using GUtilIdlePool
2020-04-14 12:34:42 +03:00
Slava Monich
e45e640f3c [gbinder] Stop using GUtilIdlePool. JB#49512
It won't work with a non-glib event loop. And one of those objects
turned out to actually be unused.
2020-04-11 02:26:46 +03:00
Slava Monich
75e8015c43 [gbinder] Added internal event loop utilities. JB#49512
gbinder_idle_callback_schedule_new = gbinder_idle_callback_new +
and gbinder_idle_callback_schedule

gbinder_idle_callback_destroy = gbinder_idle_callback_cancel +
gbinder_idle_callback_unref
2020-04-11 02:22:22 +03:00
Slava Monich
2c52fcc156 Version 1.0.40 2020-04-09 17:24:06 +03:00
Slava Monich
dc5b51a41f Merge pull request #44 from monich/event-loop
Pluggable event loop integration
2020-04-09 17:18:29 +03:00
Slava Monich
d12cee4690 [unit] Added eventloop test. JB#49512 2020-04-06 17:22:55 +03:00
Slava Monich
a74c4ac148 [gbinder] Virtualize event loop. JB#49512
This makes it possible to make libgbinder work with e.g. Qt event loop
based on QEventDispatcherUNIX (rather than QEventDispatcherGlib).
2020-04-04 20:26:06 +03:00
Slava Monich
53e50a8107 Version 1.0.39 2020-04-02 18:08:05 +03:00
Slava Monich
e896ba94cc Merge pull request #43 from mer-hybris/side-by-side-linking
Fix linking for side-by-side builds
2020-04-02 18:04:56 +03:00
Matti Lehtimäki
87ff990c73 [build] Fix linking for side-by-side builds. JB#49231 2020-04-02 14:48:16 +00:00
48 changed files with 1619 additions and 353 deletions

10
.gitignore vendored
View File

@@ -1,13 +1,11 @@
*~
debian/files
debian/libgbinder-dev.debhelper.log
debian/libgbinder-dev.substvars
debian/libgbinder-dev
debian/libgbinder.debhelper.log
debian/libgbinder.postinst.debhelper
debian/libgbinder.postrm.debhelper
debian/libgbinder.substvars
debian/libgbinder
debian/*.debhelper.log
debian/*.debhelper
debian/*.substvars
debian/*.install
debian/tmp
documentation.list
installroot

View File

@@ -16,7 +16,7 @@
VERSION_MAJOR = 1
VERSION_MINOR = 0
VERSION_RELEASE = 38
VERSION_RELEASE = 43
# Version for pkg-config
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
@@ -79,6 +79,7 @@ SRC = \
gbinder_cleanup.c \
gbinder_client.c \
gbinder_driver.c \
gbinder_eventloop.c \
gbinder_io_32.c \
gbinder_io_64.c \
gbinder_ipc.c \
@@ -119,6 +120,7 @@ COVERAGE_BUILD_DIR = $(BUILD_DIR)/coverage
#
CC ?= $(CROSS_COMPILE)gcc
STRIP ?= strip
LD = $(CC)
WARNINGS = -Wall -Wstrict-aliasing -Wunused-result
INCLUDES += -I$(INCLUDE_DIR)
@@ -131,10 +133,7 @@ DEBUG_FLAGS = -g
RELEASE_FLAGS =
COVERAGE_FLAGS = -g
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
KEEP_SYMBOLS ?= 0
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
endif
@@ -178,13 +177,15 @@ DEBUG_SO = $(DEBUG_BUILD_DIR)/$(LIB_SO)
RELEASE_SO = $(RELEASE_BUILD_DIR)/$(LIB_SO)
DEBUG_LINK = $(DEBUG_BUILD_DIR)/$(LIB_SYMLINK1)
RELEASE_LINK = $(RELEASE_BUILD_DIR)/$(LIB_SYMLINK1)
DEBUG_DEV_LINK = $(DEBUG_BUILD_DIR)/$(LIB_DEV_SYMLINK)
RELEASE_DEV_LINK = $(RELEASE_BUILD_DIR)/$(LIB_DEV_SYMLINK)
DEBUG_LIB = $(DEBUG_BUILD_DIR)/$(LIB)
RELEASE_LIB = $(RELEASE_BUILD_DIR)/$(LIB)
COVERAGE_LIB = $(COVERAGE_BUILD_DIR)/$(LIB)
debug: $(DEBUG_SO)
debug: $(DEBUG_SO) $(DEBUG_LINK) $(DEBUG_DEV_LINK)
release: $(RELEASE_SO)
release: $(RELEASE_SO) $(RELEASE_LINK) $(RELEASE_DEV_LINK)
debug_lib: $(DEBUG_LIB)
@@ -230,6 +231,7 @@ clean:
rm -fr debian/tmp debian/libgbinder debian/libgbinder-dev
rm -f documentation.list debian/files debian/*.substvars
rm -f debian/*.debhelper.log debian/*.debhelper debian/*~
rm -f debian/*.install
test:
make -C unit test
@@ -257,13 +259,11 @@ $(COVERAGE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
$(DEBUG_SO): $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) -o $@
ln -sf $(LIB_SO) $(DEBUG_LINK)
$(RELEASE_SO): $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) -o $@
ln -sf $(LIB_SO) $(RELEASE_LINK)
ifeq ($(KEEP_SYMBOLS),0)
strip $@
$(STRIP) $@
endif
$(DEBUG_LIB): $(DEBUG_OBJS)
@@ -274,12 +274,35 @@ $(RELEASE_LIB): $(RELEASE_OBJS)
$(AR) rc $@ $?
ranlib $@
$(DEBUG_LINK):
ln -sf $(LIB_SO) $@
$(RELEASE_LINK):
ln -sf $(LIB_SO) $@
$(DEBUG_DEV_LINK):
ln -sf $(LIB_SYMLINK1) $@
$(RELEASE_DEV_LINK):
ln -sf $(LIB_SYMLINK1) $@
$(COVERAGE_LIB): $(COVERAGE_OBJS)
$(AR) rc $@ $?
ranlib $@
#
# LIBDIR usually gets substituted with arch specific dir.
# It's relative in deb build and can be whatever in rpm build.
#
LIBDIR ?= usr/lib
ABS_LIBDIR := $(shell echo /$(LIBDIR) | sed -r 's|/+|/|g')
$(PKGCONFIG): $(LIB_NAME).pc.in Makefile
sed -e 's/\[version\]/'$(PCVERSION)/g $< > $@
sed -e 's|@version@|$(PCVERSION)|g' -e 's|@libdir@|$(ABS_LIBDIR)|g' $< > $@
debian/%.install: debian/%.install.in
sed 's|@LIBDIR@|$(LIBDIR)|g' $< > $@
#
# Install
@@ -291,9 +314,9 @@ INSTALL = install
INSTALL_DIRS = $(INSTALL) -d
INSTALL_FILES = $(INSTALL) -m $(INSTALL_PERM)
INSTALL_LIB_DIR = $(DESTDIR)/usr/lib
INSTALL_LIB_DIR = $(DESTDIR)$(ABS_LIBDIR)
INSTALL_INCLUDE_DIR = $(DESTDIR)/usr/include/$(NAME)
INSTALL_PKGCONFIG_DIR = $(DESTDIR)/usr/lib/pkgconfig
INSTALL_PKGCONFIG_DIR = $(DESTDIR)$(ABS_LIBDIR)/pkgconfig
install: $(INSTALL_LIB_DIR)
$(INSTALL_FILES) $(RELEASE_SO) $(INSTALL_LIB_DIR)

32
debian/changelog vendored
View File

@@ -1,3 +1,35 @@
libgbinder (1.0.43) unstable; urgency=low
* Hide internal symbols
* Respect arch specific lib dir
* Allow strip command to be replaced via environment variable
-- Slava Monich <slava.monich@jolla.com> Wed, 03 Jun 2020 15:15:40 +0300
libgbinder (1.0.42) unstable; urgency=low
* Allow GBinderClient to use multiple interfaces
-- Slava Monich <slava.monich@jolla.com> Tue, 05 May 2020 19:56:39 +0300
libgbinder (1.0.41) unstable; urgency=low
* Stop using GUtilIdlePool
-- Slava Monich <slava.monich@jolla.com> Tue, 14 Apr 2020 12:36:54 +0300
libgbinder (1.0.40) unstable; urgency=low
* Support integration with non-glib event loops
-- Slava Monich <slava.monich@jolla.com> Thu, 09 Apr 2020 17:22:12 +0300
libgbinder (1.0.39) unstable; urgency=low
* Adapted to side-by-side linking
-- Slava Monich <slava.monich@jolla.com> Thu, 02 Apr 2020 18:07:16 +0300
libgbinder (1.0.38) unstable; urgency=low
* Allow to configure log level via environment

2
debian/control vendored
View File

@@ -2,7 +2,7 @@ Source: libgbinder
Section: libs
Priority: optional
Maintainer: Slava Monich <slava.monich@jolla.com>
Build-Depends: debhelper (>= 7), libglib2.0-dev (>= 2.0), libglibutil (>= 1.0.35)
Build-Depends: debhelper (>= 8.1.3), libglib2.0-dev (>= 2.0), libglibutil (>= 1.0.35)
Standards-Version: 3.8.4
Package: libgbinder

View File

@@ -1,3 +0,0 @@
debian/tmp/usr/lib/libgbinder.so usr/lib
include/*.h usr/include/gbinder
build/libgbinder.pc usr/lib/pkgconfig

3
debian/libgbinder-dev.install.in vendored Normal file
View File

@@ -0,0 +1,3 @@
debian/tmp/@LIBDIR@/libgbinder.so @LIBDIR@
debian/tmp/@LIBDIR@/pkgconfig/libgbinder.pc @LIBDIR@/pkgconfig
debian/tmp/usr/include/* usr/include

View File

@@ -1 +0,0 @@
debian/tmp/usr/lib/libgbinder.so.* usr/lib

1
debian/libgbinder.install.in vendored Normal file
View File

@@ -0,0 +1 @@
debian/tmp/@LIBDIR@/libgbinder.so.* @LIBDIR@

7
debian/rules vendored
View File

@@ -4,8 +4,13 @@
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
LIBDIR=usr/lib/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
override_dh_auto_build:
dh_auto_build -- LIBDIR=$(LIBDIR) release pkgconfig debian/libgbinder.install debian/libgbinder-dev.install
override_dh_auto_install:
dh_auto_install -- install-dev
dh_auto_install -- LIBDIR=$(LIBDIR) install-dev
%:
dh $@

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -37,6 +37,11 @@
G_BEGIN_DECLS
typedef struct gbinder_client_iface_info {
const char* iface;
guint32 last_code;
} GBinderClientIfaceInfo;
typedef
void
(*GBinderClientReplyFunc)(
@@ -50,6 +55,12 @@ gbinder_client_new(
GBinderRemoteObject* object,
const char* iface);
GBinderClient*
gbinder_client_new2(
GBinderRemoteObject* object,
const GBinderClientIfaceInfo* ifaces,
gsize count); /* since 1.0.42 */
GBinderClient*
gbinder_client_ref(
GBinderClient* client);
@@ -62,10 +73,20 @@ const char*
gbinder_client_interface(
GBinderClient* client); /* since 1.0.22 */
const char*
gbinder_client_interface2(
GBinderClient* client,
guint32 code); /* since 1.0.42 */
GBinderLocalRequest*
gbinder_client_new_request(
GBinderClient* client);
GBinderLocalRequest*
gbinder_client_new_request2(
GBinderClient* client,
guint32 code); /* since 1.0.42 */
GBinderRemoteReply*
gbinder_client_transact_sync_reply(
GBinderClient* client,

194
include/gbinder_eventloop.h Normal file
View File

@@ -0,0 +1,194 @@
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GBINDER_EVENTLOOP_H
#define GBINDER_EVENTLOOP_H
#include "gbinder_types.h"
G_BEGIN_DECLS
/* Since 1.0.40 */
typedef struct gbinder_eventloop_integration GBinderEventLoopIntegration;
typedef void (*GBinderEventLoopCallbackFunc)(gpointer data);
typedef struct gbinder_eventloop_timeout {
const GBinderEventLoopIntegration* eventloop;
} GBinderEventLoopTimeout;
typedef struct gbinder_eventloop_callback {
const GBinderEventLoopIntegration* eventloop;
} GBinderEventLoopCallback;
/**
* Main event loop integration. There is only one main event loop in the
* process (by definition).
*
* By default, GLib event loop is being used for callbacks and timeouts.
*
* It may be necessary to replace it with e.g. Qt event loop. Quite often
* Qt event loop is implemented by QEventDispatcherGlib which is sitting
* on top of GLib event and therefore works with the default implementation.
* But it won't work with e.g. QEventDispatcherUNIX.
*
* For Qt programs that use QEventDispatcherUNIX, it needs to be replaced
* with the one provided by libqbinder.
*/
typedef struct gbinder_eventloop_integration {
/**
* timeout_add
*
* Sets a function to be called at regular intervals (in milliseconds).
* If the function returns G_SOURCE_REMOVE, timeout is automatically
* destroyed (you must not call timeout_remove in this case). If the
* function returns G_SOURCE_CONTINUE, it will be called again after
* the same interval.
*/
GBinderEventLoopTimeout* (*timeout_add)(guint millis, GSourceFunc func,
gpointer data);
/**
* timeout_remove
*
* Removes a pending timeout and destroys it. The caller makes sure that
* argument is not NULL. Note that timeout is automatically destroyed if
* the callback function returns G_SOURCE_REMOVE.
*/
void (*timeout_remove)(GBinderEventLoopTimeout* timeout);
/**
* callback_new
*
* Creates a callback object. It returns you a reference, you must
* eventually pass the returned object to callback_unref to drop
* this reference.
*
* Note that it doesn't automatically schedule the callback. You
* must explicitly call callback_schedule to actually schedule it.
* The finalize function is invoked regardless of whether callback
* was cancelled or not.
*/
GBinderEventLoopCallback* (*callback_new)(GBinderEventLoopCallbackFunc fun,
gpointer data, GDestroyNotify finalize);
/**
* callback_ref
*
* Increments the reference count. That prevents the object from being
* deleted before you drop this reference. The caller makes sure that
* argument is not NULL.
*/
void (*callback_ref)(GBinderEventLoopCallback* cb);
/**
* callback_unref
*
* Decrements the reference count (drops the reference). When reference
* count reaches zero, the object gets deleted. The caller makes sure
* that argument is not NULL.
*
* Note that calling callback_schedule temporarily adds an internal
* reference until the callback is invoked or callback_cancel is called,
* whichever happens first.
*/
void (*callback_unref)(GBinderEventLoopCallback* cb);
/**
* callback_schedule
*
* Schedules the callback to be invoked in the main loop at some point
* in the future (but as soon as possible). The caller makes sure that
* argument is not NULL.
*
* This adds an internal reference to the GBinderEventLoopCallback object
* until the callback is invoked or callback_cancel is called, whichever
* happens first.
*/
void (*callback_schedule)(GBinderEventLoopCallback* cb);
/**
* callback_cancel
*
* Makes sure that callback won't be invoked (if it hasn't been
* invoked yet) and drops the internal reference. Does nothing
* if the callback has already been invoked. The caller makes sure that
* argument is not NULL.
*/
void (*callback_cancel)(GBinderEventLoopCallback* cb);
/**
* cleanup
*
* This function is called when event loop integration is being replaced
* with a different one, or libgbinder is being unloaded.
*/
void (*cleanup)(void);
/* Padding for future expansion */
void (*_reserved1)(void);
void (*_reserved2)(void);
void (*_reserved3)(void);
void (*_reserved4)(void);
void (*_reserved5)(void);
void (*_reserved6)(void);
void (*_reserved7)(void);
void (*_reserved8)(void);
void (*_reserved9)(void);
/*
* api_level will remain zero (and ignored) until we run out of
* the above placeholders. Hopefully, forever.
*/
int api_level;
} GBinderEventLoopIntegration;
/**
* gbinder_eventloop_set should be called before libgbinder creates any of
* its internal threads. And it must be done from the main thread.
*/
void
gbinder_eventloop_set(
const GBinderEventLoopIntegration* loop);
G_END_DECLS
#endif /* GBINDER_EVENTLOOP_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -1,10 +1,10 @@
name=gbinder
libdir=/usr/lib
libdir=@libdir@
includedir=/usr/include
Name: libgbinder
Description: Binder client library
Version: [version]
Requires: glib-2.0 libglibutil
Version: @version@
Requires.private: glib-2.0 libglibutil
Libs: -L${libdir} -l${name}
Cflags: -I${includedir} -I${includedir}/${name}

View File

@@ -1,14 +1,16 @@
Name: libgbinder
Version: 1.0.38
Version: 1.0.43
Release: 0
Summary: Binder client library
Group: Development/Libraries
License: BSD
URL: https://github.com/mer-hybris/libgbinder
Source: %{name}-%{version}.tar.bz2
Requires: libglibutil >= 1.0.35
%define libglibutil_version 1.0.35
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libglibutil) >= 1.0.35
BuildRequires: pkgconfig(libglibutil) >= %{libglibutil_version}
Requires: libglibutil >= %{libglibutil_version}
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
@@ -27,11 +29,11 @@ This package contains the development library for %{name}.
%setup -q
%build
make KEEP_SYMBOLS=1 release pkgconfig
make LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig
%install
rm -rf %{buildroot}
make install-dev DESTDIR=%{buildroot}
make LIBDIR=%{_libdir} DESTDIR=%{buildroot} install-dev
%check
make -C unit test

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -42,42 +42,51 @@ gbinder_buffer_new(
GBinderDriver* driver,
void* data,
gsize size,
void** objects);
void** objects)
GBINDER_INTERNAL;
GBinderBuffer*
gbinder_buffer_new_with_parent(
GBinderBuffer* parent,
void* data,
gsize size);
gsize size)
GBINDER_INTERNAL;
GBinderDriver*
gbinder_buffer_driver(
GBinderBuffer* buf);
GBinderBuffer* buf)
GBINDER_INTERNAL;
GBinderBufferContents*
gbinder_buffer_contents(
GBinderBuffer* buf);
GBinderBuffer* buf)
GBINDER_INTERNAL;
gconstpointer
gbinder_buffer_data(
GBinderBuffer* buf,
gsize* size);
gsize* size)
GBINDER_INTERNAL;
const GBinderIo*
gbinder_buffer_io(
GBinderBuffer* buf);
GBinderBuffer* buf)
GBINDER_INTERNAL;
void**
gbinder_buffer_objects(
GBinderBuffer* buffer);
GBinderBuffer* buffer)
GBINDER_INTERNAL;
GBinderBufferContents*
gbinder_buffer_contents_ref(
GBinderBufferContents* contents);
GBinderBufferContents* contents)
GBINDER_INTERNAL;
void
gbinder_buffer_contents_unref(
GBinderBufferContents* contents);
GBinderBufferContents* contents)
GBINDER_INTERNAL;
#endif /* GBINDER_BUFFER_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -37,17 +37,20 @@
void
gbinder_cleanup_free(
GBinderCleanup* cleanup);
GBinderCleanup* cleanup)
GBINDER_INTERNAL;
void
gbinder_cleanup_reset(
GBinderCleanup* cleanup);
GBinderCleanup* cleanup)
GBINDER_INTERNAL;
GBinderCleanup*
gbinder_cleanup_add(
GBinderCleanup* cleanup,
GDestroyNotify destroy,
gpointer pointer);
gpointer pointer)
GBINDER_INTERNAL;
#endif /* GBINDER_CLEANUP_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -41,14 +41,22 @@
#include <gutil_macros.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
typedef struct gbinder_client_iface_range {
char* iface;
GBytes* rpc_header;
GBinderLocalRequest* basic_req;
guint32 last_code;
} GBinderClientIfaceRange;
typedef struct gbinder_client_priv {
GBinderClient pub;
guint32 refcount;
char* iface;
GBytes* rpc_header;
GBinderLocalRequest* basic_req;
GBinderClientIfaceRange* ranges;
guint nr;
} GBinderClientPriv;
typedef struct gbinder_client_tx {
@@ -65,19 +73,79 @@ static inline GBinderClientPriv* gbinder_client_cast(GBinderClient* client)
* Implementation
*==========================================================================*/
static
const GBinderClientIfaceRange*
gbinder_client_find_range(
GBinderClientPriv* priv,
guint32 code)
{
guint i;
for (i = 0; i < priv->nr; i++) {
const GBinderClientIfaceRange* r = priv->ranges + i;
if (r->last_code >= code) {
return r;
}
}
return NULL;
}
/*
* Generates basic request (without additional parameters) for the
* specified interface and pulls header data out of it. The basic
* request can be reused for those transactions which have no
* additional parameters. The header data are needed for building
* non-trivial requests.
*/
static
void
gbinder_client_init_range(
GBinderClientIfaceRange* r,
GBinderDriver* driver,
const GBinderClientIfaceInfo* info)
{
GBinderOutputData* hdr;
r->basic_req = gbinder_driver_local_request_new(driver, info->iface);
hdr = gbinder_local_request_data(r->basic_req);
r->rpc_header = g_bytes_new(hdr->bytes->data, hdr->bytes->len);
r->iface = g_strdup(info->iface);
r->last_code = info->last_code;
}
static
int
gbinder_client_sort_ranges(
const void* p1,
const void* p2)
{
const GBinderClientIfaceRange* r1 = p1;
const GBinderClientIfaceRange* r2 = p2;
return (r1->last_code < r2->last_code) ? (-1) :
(r1->last_code > r2->last_code) ? 1 : 0;
}
static
void
gbinder_client_free(
GBinderClientPriv* priv)
{
GBinderClient* self = &priv->pub;
guint i;
gbinder_remote_object_unref(self->remote);
gbinder_local_request_unref(priv->basic_req);
g_free(priv->iface);
if (priv->rpc_header) {
g_bytes_unref(priv->rpc_header);
for (i = 0; i < priv->nr; i++) {
GBinderClientIfaceRange* r = priv->ranges + i;
gbinder_local_request_unref(r->basic_req);
g_free(r->iface);
if (r->rpc_header) {
g_bytes_unref(r->rpc_header);
}
}
g_free(priv->ranges);
gbinder_remote_object_unref(self->remote);
g_slice_free(GBinderClientPriv, priv);
}
@@ -115,9 +183,10 @@ gbinder_client_transact_destroy(
*==========================================================================*/
GBinderClient*
gbinder_client_new(
gbinder_client_new2(
GBinderRemoteObject* remote,
const char* iface)
const GBinderClientIfaceInfo* ifaces,
gsize count)
{
if (G_LIKELY(remote)) {
GBinderClientPriv* priv = g_slice_new0(GBinderClientPriv);
@@ -126,22 +195,22 @@ gbinder_client_new(
g_atomic_int_set(&priv->refcount, 1);
self->remote = gbinder_remote_object_ref(remote);
if (count > 0) {
gsize i;
/*
* Generate basic request (without additional parameters) and pull
* header data out of it. The basic request can be reused for those
* transactions which has no additional parameters. The header data
* are needed for building non-trivial requests.
*/
if (iface) {
GBinderOutputData* hdr;
priv->basic_req = gbinder_driver_local_request_new(driver, iface);
hdr = gbinder_local_request_data(priv->basic_req);
priv->rpc_header = g_bytes_new(hdr->bytes->data, hdr->bytes->len);
self->iface = priv->iface = g_strdup(iface);
priv->nr = count;
priv->ranges = g_new(GBinderClientIfaceRange, priv->nr);
for (i = 0; i < count; i++) {
gbinder_client_init_range(priv->ranges + i, driver, ifaces + i);
}
qsort(priv->ranges, count, sizeof(GBinderClientIfaceRange),
gbinder_client_sort_ranges);
} else {
priv->basic_req = gbinder_local_request_new
/* No interface info */
priv->nr = 1;
priv->ranges = g_new0(GBinderClientIfaceRange, 1);
priv->ranges[0].last_code = UINT_MAX;
priv->ranges[0].basic_req = gbinder_local_request_new
(gbinder_driver_io(driver), NULL);
}
return self;
@@ -149,6 +218,18 @@ gbinder_client_new(
return NULL;
}
GBinderClient*
gbinder_client_new(
GBinderRemoteObject* remote,
const char* iface)
{
GBinderClientIfaceInfo info;
info.iface = iface;
info.last_code = UINT_MAX;
return gbinder_client_new2(remote, &info, 1);
}
GBinderClient*
gbinder_client_ref(
GBinderClient* self)
@@ -180,7 +261,23 @@ const char*
gbinder_client_interface(
GBinderClient* self) /* since 1.0.22 */
{
return G_LIKELY(self) ? gbinder_client_cast(self)->iface : NULL;
return G_LIKELY(self) ? gbinder_client_cast(self)->ranges->iface : NULL;
}
const char*
gbinder_client_interface2(
GBinderClient* self,
guint32 code) /* since 1.0.42 */
{
if (G_LIKELY(self)) {
const GBinderClientIfaceRange* r =
gbinder_client_find_range(gbinder_client_cast(self), code);
if (r) {
return r->iface;
}
}
return NULL;
}
GBinderLocalRequest*
@@ -190,7 +287,27 @@ gbinder_client_new_request(
if (G_LIKELY(self)) {
GBinderClientPriv* priv = gbinder_client_cast(self);
const GBinderIo* io = gbinder_driver_io(self->remote->ipc->driver);
return gbinder_local_request_new(io, priv->rpc_header);
return gbinder_local_request_new(io, priv->ranges->rpc_header);
}
return NULL;
}
GBinderLocalRequest*
gbinder_client_new_request2(
GBinderClient* self,
guint32 code) /* since 1.0.42 */
{
if (G_LIKELY(self)) {
GBinderClientPriv* priv = gbinder_client_cast(self);
const GBinderClientIfaceRange* r = gbinder_client_find_range
(priv, code);
if (r) {
const GBinderIo* io = gbinder_driver_io(self->remote->ipc->driver);
return gbinder_local_request_new(io, r->rpc_header);
}
}
return NULL;
}
@@ -207,8 +324,13 @@ gbinder_client_transact_sync_reply(
if (G_LIKELY(!obj->dead)) {
if (!req) {
const GBinderClientIfaceRange* r = gbinder_client_find_range
(gbinder_client_cast(self), code);
/* Default empty request (just the header, no parameters) */
req = gbinder_client_cast(self)->basic_req;
if (r) {
req = r->basic_req;
}
}
return gbinder_ipc_transact_sync_reply(obj->ipc, obj->handle,
code, req, status);
@@ -229,8 +351,13 @@ gbinder_client_transact_sync_oneway(
if (G_LIKELY(!obj->dead)) {
if (!req) {
const GBinderClientIfaceRange* r = gbinder_client_find_range
(gbinder_client_cast(self), code);
/* Default empty request (just the header, no parameters) */
req = gbinder_client_cast(self)->basic_req;
if (r) {
req = r->basic_req;
}
}
return gbinder_ipc_transact_sync_oneway(obj->ipc, obj->handle,
code, req);
@@ -263,8 +390,13 @@ gbinder_client_transact(
tx->user_data = user_data;
if (!req) {
const GBinderClientIfaceRange* r = gbinder_client_find_range
(gbinder_client_cast(self), code);
/* Default empty request (just the header, no parameters) */
req = gbinder_client_cast(self)->basic_req;
if (r) {
req = r->basic_req;
}
}
return gbinder_ipc_transact(obj->ipc, obj->handle, code,

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -13,9 +13,9 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Jolla Ltd nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -38,7 +38,6 @@
#include "gbinder_types_p.h"
struct gbinder_client {
const char* iface;
GBinderRemoteObject* remote;
};

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -33,6 +33,7 @@
#include "gbinder_servicemanager_p.h"
#include "gbinder_rpc_protocol.h"
#include "gbinder_servicepoll.h"
#include "gbinder_eventloop_p.h"
#include "gbinder_log.h"
#include <gbinder_client.h>
@@ -48,7 +49,7 @@ typedef struct gbinder_defaultservicemanager_watch {
GBinderServicePoll* poll;
char* name;
gulong handler_id;
guint notify_id;
GBinderEventLoopTimeout* notify;
} GBinderDefaultServiceManagerWatch;
typedef GBinderServiceManagerClass GBinderDefaultServiceManagerClass;
@@ -99,9 +100,9 @@ gbinder_defaultservicemanager_watch_proc(
GBinderServiceManager* manager =
gbinder_servicepoll_manager(watch->poll);
if (watch->notify_id) {
g_source_remove(watch->notify_id);
watch->notify_id = 0;
if (watch->notify) {
gbinder_timeout_remove(watch->notify);
watch->notify = NULL;
}
gbinder_servicemanager_service_registered(manager, name_added);
}
@@ -116,8 +117,8 @@ gbinder_defaultservicemanager_watch_notify(
GBinderServiceManager* manager = gbinder_servicepoll_manager(watch->poll);
char* name = g_strdup(watch->name);
GASSERT(watch->notify_id);
watch->notify_id = 0;
GASSERT(watch->notify);
watch->notify = NULL;
gbinder_servicemanager_service_registered(manager, name);
g_free(name);
return G_SOURCE_REMOVE;
@@ -130,9 +131,7 @@ gbinder_defaultservicemanager_watch_free(
{
GBinderDefaultServiceManagerWatch* watch = user_data;
if (watch->notify_id) {
g_source_remove(watch->notify_id);
}
gbinder_timeout_remove(watch->notify);
gbinder_servicepoll_remove_handler(watch->poll, watch->handler_id);
gbinder_servicepoll_unref(watch->poll);
g_free(watch->name);
@@ -258,8 +257,8 @@ gbinder_defaultservicemanager_watch(
g_hash_table_replace(self->watch_table, watch->name, watch);
if (gbinder_servicepoll_is_known_name(watch->poll, name)) {
watch->notify_id =
g_idle_add(gbinder_defaultservicemanager_watch_notify, watch);
watch->notify = gbinder_idle_add
(gbinder_defaultservicemanager_watch_notify, watch);
}
return TRUE;
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -40,87 +40,105 @@ struct pollfd;
GBinderDriver*
gbinder_driver_new(
const char* dev,
const GBinderRpcProtocol* protocol);
const GBinderRpcProtocol* protocol)
GBINDER_INTERNAL;
GBinderDriver*
gbinder_driver_ref(
GBinderDriver* driver);
GBinderDriver* driver)
GBINDER_INTERNAL;
void
gbinder_driver_unref(
GBinderDriver* driver);
GBinderDriver* driver)
GBINDER_INTERNAL;
int
gbinder_driver_fd(
GBinderDriver* driver);
GBinderDriver* driver)
GBINDER_INTERNAL;
int
gbinder_driver_poll(
GBinderDriver* driver,
struct pollfd* pollfd);
struct pollfd* pollfd)
GBINDER_INTERNAL;
const char*
gbinder_driver_dev(
GBinderDriver* driver);
GBinderDriver* driver)
GBINDER_INTERNAL;
const GBinderIo*
gbinder_driver_io(
GBinderDriver* driver);
GBinderDriver* driver)
GBINDER_INTERNAL;
gboolean
gbinder_driver_request_death_notification(
GBinderDriver* driver,
GBinderRemoteObject* obj);
GBinderRemoteObject* obj)
GBINDER_INTERNAL;
gboolean
gbinder_driver_clear_death_notification(
GBinderDriver* driver,
GBinderRemoteObject* obj);
GBinderRemoteObject* obj)
GBINDER_INTERNAL;
gboolean
gbinder_driver_increfs(
GBinderDriver* driver,
guint32 handle);
guint32 handle)
GBINDER_INTERNAL;
gboolean
gbinder_driver_decrefs(
GBinderDriver* driver,
guint32 handle);
guint32 handle)
GBINDER_INTERNAL;
gboolean
gbinder_driver_acquire(
GBinderDriver* driver,
guint32 handle);
guint32 handle)
GBINDER_INTERNAL;
gboolean
gbinder_driver_release(
GBinderDriver* driver,
guint32 handle);
guint32 handle)
GBINDER_INTERNAL;
void
gbinder_driver_close_fds(
GBinderDriver* self,
void** objects,
const void* end);
const void* end)
GBINDER_INTERNAL;
void
gbinder_driver_free_buffer(
GBinderDriver* driver,
void* buffer);
void* buffer)
GBINDER_INTERNAL;
gboolean
gbinder_driver_enter_looper(
GBinderDriver* driver);
GBinderDriver* driver)
GBINDER_INTERNAL;
gboolean
gbinder_driver_exit_looper(
GBinderDriver* driver);
GBinderDriver* driver)
GBINDER_INTERNAL;
int
gbinder_driver_read(
GBinderDriver* driver,
GBinderObjectRegistry* reg,
GBinderHandler* handler);
GBinderHandler* handler)
GBINDER_INTERNAL;
int
gbinder_driver_transact(
@@ -129,18 +147,21 @@ gbinder_driver_transact(
guint32 handle,
guint32 code,
GBinderLocalRequest* request,
GBinderRemoteReply* reply);
GBinderRemoteReply* reply)
GBINDER_INTERNAL;
int
gbinder_driver_ping(
GBinderDriver* driver,
GBinderObjectRegistry* reg,
guint32 handle);
guint32 handle)
GBINDER_INTERNAL;
GBinderLocalRequest*
gbinder_driver_local_request_new(
GBinderDriver* self,
const char* iface);
const char* iface)
GBINDER_INTERNAL;
#endif /* GBINDER_DRIVER_H */

347
src/gbinder_eventloop.c Normal file
View File

@@ -0,0 +1,347 @@
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gbinder_eventloop_p.h"
#include <gutil_macros.h>
#define GBINDER_DEFAULT_EVENTLOOP (&gbinder_eventloop_glib)
static const GBinderEventLoopIntegration gbinder_eventloop_glib;
/*==========================================================================*
* GLib event loop integration
*==========================================================================*/
typedef struct gbinder_eventloop_glib_timeout {
GBinderEventLoopTimeout timeout;
guint id;
GSourceFunc func;
gpointer data;
} GBinderEventLoopTimeoutGLib;
typedef struct gbinder_eventloop_glib_callback {
GSource source;
GBinderEventLoopCallback callback;
} GBinderEventLoopCallbackGLib;
static
inline
GBinderEventLoopTimeoutGLib*
gbinder_eventloop_glib_timeout_cast(
GBinderEventLoopTimeout* timeout)
{
return G_CAST(timeout,GBinderEventLoopTimeoutGLib,timeout);
}
static
inline
GSource*
gbinder_eventloop_glib_callback_source(
GBinderEventLoopCallback* callback)
{
return &(G_CAST(callback,GBinderEventLoopCallbackGLib,callback)->source);
}
static
gboolean
gbinder_eventloop_glib_timeout_callback(
gpointer data)
{
GBinderEventLoopTimeoutGLib* timeout = data;
return timeout->func(timeout->data);
}
static
void
gbinder_eventloop_glib_timeout_finalize(
gpointer data)
{
g_slice_free1(sizeof(GBinderEventLoopTimeoutGLib), data);
}
static
GBinderEventLoopTimeout*
gbinder_eventloop_glib_timeout_add(
guint interval,
GSourceFunc func,
gpointer data)
{
GBinderEventLoopTimeoutGLib* impl =
g_slice_new(GBinderEventLoopTimeoutGLib);
impl->timeout.eventloop = &gbinder_eventloop_glib;
impl->func = func;
impl->data = data;
impl->id = g_timeout_add_full(G_PRIORITY_DEFAULT, interval,
gbinder_eventloop_glib_timeout_callback, impl,
gbinder_eventloop_glib_timeout_finalize);
return &impl->timeout;
}
static
void
gbinder_eventloop_glib_timeout_remove(
GBinderEventLoopTimeout* timeout)
{
g_source_remove(gbinder_eventloop_glib_timeout_cast(timeout)->id);
}
static
gboolean
gbinder_eventloop_glib_callback_prepare(
GSource* source,
gint* timeout)
{
*timeout = 0;
return TRUE;
}
static
gboolean
gbinder_eventloop_glib_callback_check(
GSource* source)
{
return TRUE;
}
static
gboolean
gbinder_eventloop_glib_callback_dispatch(
GSource* source,
GSourceFunc callback,
gpointer user_data)
{
((GBinderEventLoopCallbackFunc)callback)(user_data);
return G_SOURCE_REMOVE;
}
static
GBinderEventLoopCallback*
gbinder_eventloop_glib_callback_new(
GBinderEventLoopCallbackFunc func,
gpointer data,
GDestroyNotify finalize)
{
static GSourceFuncs callback_funcs = {
gbinder_eventloop_glib_callback_prepare,
gbinder_eventloop_glib_callback_check,
gbinder_eventloop_glib_callback_dispatch
};
GBinderEventLoopCallbackGLib* impl = (GBinderEventLoopCallbackGLib*)
g_source_new(&callback_funcs, sizeof(GBinderEventLoopCallbackGLib));
impl->callback.eventloop = &gbinder_eventloop_glib;
g_source_set_callback(&impl->source, (GSourceFunc) func, data, finalize);
return &impl->callback;
}
static
void
gbinder_eventloop_glib_callback_ref(
GBinderEventLoopCallback* cb)
{
g_source_ref(gbinder_eventloop_glib_callback_source(cb));
}
static
void
gbinder_eventloop_glib_callback_unref(
GBinderEventLoopCallback* cb)
{
g_source_unref(gbinder_eventloop_glib_callback_source(cb));
}
static
void
gbinder_eventloop_glib_callback_schedule(
GBinderEventLoopCallback* cb)
{
static GMainContext* context = NULL;
if (!context) context = g_main_context_default();
g_source_attach(gbinder_eventloop_glib_callback_source(cb), context);
}
static
void
gbinder_eventloop_glib_callback_cancel(
GBinderEventLoopCallback* cb)
{
g_source_destroy(gbinder_eventloop_glib_callback_source(cb));
}
static
void
gbinder_eventloop_glib_cleanup(
void)
{
}
static const GBinderEventLoopIntegration gbinder_eventloop_glib = {
gbinder_eventloop_glib_timeout_add,
gbinder_eventloop_glib_timeout_remove,
gbinder_eventloop_glib_callback_new,
gbinder_eventloop_glib_callback_ref,
gbinder_eventloop_glib_callback_unref,
gbinder_eventloop_glib_callback_schedule,
gbinder_eventloop_glib_callback_cancel,
gbinder_eventloop_glib_cleanup
};
/*==========================================================================*
* Internal interface
*==========================================================================*/
static const GBinderEventLoopIntegration* gbinder_eventloop =
GBINDER_DEFAULT_EVENTLOOP;
GBinderEventLoopTimeout*
gbinder_timeout_add(
guint interval,
GSourceFunc function,
gpointer data)
{
return gbinder_eventloop->timeout_add(interval, function, data);
}
GBinderEventLoopTimeout*
gbinder_idle_add(
GSourceFunc function,
gpointer data)
{
return gbinder_eventloop->timeout_add(0, function, data);
}
void
gbinder_timeout_remove(
GBinderEventLoopTimeout* timeout)
{
if (timeout) {
timeout->eventloop->timeout_remove(timeout);
}
}
GBinderEventLoopCallback*
gbinder_idle_callback_new(
GBinderEventLoopCallbackFunc func,
gpointer data,
GDestroyNotify finalize)
{
return gbinder_eventloop->callback_new(func, data, finalize);
}
GBinderEventLoopCallback*
gbinder_idle_callback_schedule_new(
GBinderEventLoopCallbackFunc func,
gpointer data,
GDestroyNotify finalize)
{
GBinderEventLoopCallback* cb =
gbinder_eventloop->callback_new(func, data, finalize);
gbinder_idle_callback_schedule(cb);
return cb;
}
GBinderEventLoopCallback*
gbinder_idle_callback_ref(
GBinderEventLoopCallback* cb)
{
if (cb) {
cb->eventloop->callback_ref(cb);
return cb;
}
return NULL;
}
void
gbinder_idle_callback_unref(
GBinderEventLoopCallback* cb)
{
if (cb) {
cb->eventloop->callback_unref(cb);
}
}
void
gbinder_idle_callback_schedule(
GBinderEventLoopCallback* cb)
{
if (cb) {
cb->eventloop->callback_schedule(cb);
}
}
void
gbinder_idle_callback_cancel(
GBinderEventLoopCallback* cb)
{
if (cb) {
cb->eventloop->callback_cancel(cb);
}
}
void
gbinder_idle_callback_destroy(
GBinderEventLoopCallback* cb)
{
if (cb) {
const GBinderEventLoopIntegration* eventloop = cb->eventloop;
eventloop->callback_cancel(cb);
eventloop->callback_unref(cb);
}
}
void
gbinder_eventloop_set(
const GBinderEventLoopIntegration* loop)
{
if (!loop) loop = GBINDER_DEFAULT_EVENTLOOP;
if (gbinder_eventloop != loop) {
const GBinderEventLoopIntegration* prev = gbinder_eventloop;
gbinder_eventloop = loop;
prev->cleanup();
}
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

104
src/gbinder_eventloop_p.h Normal file
View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GBINDER_EVENTLOOP_PRIVATE_H
#define GBINDER_EVENTLOOP_PRIVATE_H
#include "gbinder_types_p.h"
#include "gbinder_eventloop.h"
GBinderEventLoopTimeout*
gbinder_timeout_add(
guint millis,
GSourceFunc func,
gpointer data)
GBINDER_INTERNAL;
GBinderEventLoopTimeout*
gbinder_idle_add(
GSourceFunc func,
gpointer data)
GBINDER_INTERNAL;
void
gbinder_timeout_remove(
GBinderEventLoopTimeout* timeout)
GBINDER_INTERNAL;
GBinderEventLoopCallback*
gbinder_idle_callback_new(
GBinderEventLoopCallbackFunc func,
gpointer data,
GDestroyNotify destroy)
GBINDER_INTERNAL;
GBinderEventLoopCallback*
gbinder_idle_callback_schedule_new(
GBinderEventLoopCallbackFunc func,
gpointer data,
GDestroyNotify destroy)
GBINDER_INTERNAL;
GBinderEventLoopCallback*
gbinder_idle_callback_ref(
GBinderEventLoopCallback* cb)
GBINDER_INTERNAL;
void
gbinder_idle_callback_unref(
GBinderEventLoopCallback* cb)
GBINDER_INTERNAL;
void
gbinder_idle_callback_schedule(
GBinderEventLoopCallback* cb)
GBINDER_INTERNAL;
void
gbinder_idle_callback_cancel(
GBinderEventLoopCallback* cb)
GBINDER_INTERNAL;
void
gbinder_idle_callback_destroy(
GBinderEventLoopCallback* cb)
GBINDER_INTERNAL;
#endif /* GBINDER_EVENTLOOP_PRIVATE_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -13,9 +13,9 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Jolla Ltd nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

View File

@@ -181,8 +181,8 @@ struct gbinder_io {
int (*write_read)(int fd, GBinderIoBuf* write, GBinderIoBuf* read);
};
extern const GBinderIo gbinder_io_32;
extern const GBinderIo gbinder_io_64;
extern const GBinderIo gbinder_io_32 GBINDER_INTERNAL;
extern const GBinderIo gbinder_io_64 GBINDER_INTERNAL;
#endif /* GBINDER_IO_H */

View File

@@ -43,10 +43,10 @@
#include "gbinder_remote_object_p.h"
#include "gbinder_remote_reply_p.h"
#include "gbinder_remote_request_p.h"
#include "gbinder_eventloop_p.h"
#include "gbinder_writer.h"
#include "gbinder_log.h"
#include <gutil_idlepool.h>
#include <gutil_macros.h>
#include <unistd.h>
@@ -60,7 +60,6 @@ struct gbinder_ipc_priv {
GBinderIpc* self;
GThreadPool* tx_pool;
GHashTable* tx_table;
GMainContext* context;
char* key;
GBinderObjectRegistry object_registry;
@@ -175,7 +174,7 @@ typedef struct gbinder_ipc_tx_priv {
GBinderIpcTxPrivFunc fn_exec;
GBinderIpcTxPrivFunc fn_done;
GBinderIpcTxPrivFunc fn_free;
GSource* completion;
GBinderEventLoopCallback* completion;
} GBinderIpcTxPriv;
typedef struct gbinder_ipc_tx_internal {
@@ -406,7 +405,7 @@ gbinder_ipc_looper_unref(
}
static
gboolean
void
gbinder_ipc_looper_tx_handle(
gpointer data)
{
@@ -480,7 +479,6 @@ gbinder_ipc_looper_tx_handle(
if (write(tx->pipefd[1], &done, sizeof(done)) <= 0) {
GWARN("Failed to wake up the looper");
}
return G_SOURCE_REMOVE;
}
static
@@ -593,13 +591,11 @@ gbinder_ipc_looper_transact(
GBinderIpcPriv* priv = ipc->priv;
struct pollfd fds[2];
guint8 done = 0;
GSource* source = g_idle_source_new();
gboolean was_blocked = FALSE;
/* Let GBinderLocalObject handle the transaction on the main thread */
g_source_set_callback(source, gbinder_ipc_looper_tx_handle,
gbinder_ipc_looper_tx_ref(tx), gbinder_ipc_looper_tx_done);
g_source_attach(source, priv->context);
GBinderEventLoopCallback* callback =
gbinder_idle_callback_schedule_new(gbinder_ipc_looper_tx_handle,
gbinder_ipc_looper_tx_ref(tx), gbinder_ipc_looper_tx_done);
/* Wait for either transaction completion or looper shutdown */
memset(fds, 0, sizeof(fds));
@@ -685,8 +681,7 @@ gbinder_ipc_looper_transact(
gbinder_ipc_looper_tx_unref(tx, FALSE);
}
g_source_destroy(source);
g_source_unref(source);
gbinder_idle_callback_destroy(callback);
if (was_blocked) {
guint n;
@@ -1197,7 +1192,7 @@ gbinder_ipc_tx_free(
GBinderIpc* self = pub->ipc;
GBinderIpcPriv* priv = self->priv;
g_source_unref(tx->completion);
gbinder_idle_callback_unref(tx->completion);
g_hash_table_remove(priv->tx_table, GINT_TO_POINTER(pub->id));
tx->fn_free(tx);
@@ -1206,7 +1201,7 @@ gbinder_ipc_tx_free(
}
static
gboolean
void
gbinder_ipc_tx_done(
gpointer data)
{
@@ -1216,7 +1211,6 @@ gbinder_ipc_tx_done(
if (!pub->cancelled) {
tx->fn_done(tx);
}
return G_SOURCE_REMOVE;
}
static
@@ -1247,8 +1241,7 @@ gbinder_ipc_tx_priv_init(
priv->fn_exec = fn_exec;
priv->fn_done = fn_done;
priv->fn_free = fn_free;
priv->completion = g_idle_source_new();
g_source_set_callback(priv->completion, gbinder_ipc_tx_done, priv,
priv->completion = gbinder_idle_callback_new(gbinder_ipc_tx_done, priv,
gbinder_ipc_tx_free);
}
@@ -1425,8 +1418,6 @@ gbinder_ipc_tx_proc(
gpointer object)
{
GBinderIpcTxPriv* tx = data;
GBinderIpc* self = GBINDER_IPC(object);
GBinderIpcPriv* priv = self->priv;
if (!tx->pub.cancelled) {
tx->fn_exec(tx);
@@ -1435,7 +1426,7 @@ gbinder_ipc_tx_proc(
}
/* The result is handled by the main thread */
g_source_attach(tx->completion, priv->context);
gbinder_idle_callback_schedule(tx->completion);
}
/*==========================================================================*
@@ -1641,14 +1632,12 @@ gbinder_ipc_init(
g_mutex_init(&priv->looper_mutex);
g_mutex_init(&priv->local_objects_mutex);
g_mutex_init(&priv->remote_objects_mutex);
priv->context = g_main_context_default();
priv->tx_table = g_hash_table_new(g_direct_hash, g_direct_equal);
priv->tx_pool = g_thread_pool_new(gbinder_ipc_tx_proc, self,
GBINDER_IPC_MAX_TX_THREADS, FALSE, NULL);
priv->object_registry.f = &object_registry_functions;
priv->self = self;
self->priv = priv;
self->pool = gutil_idle_pool_new();
}
static
@@ -1729,7 +1718,6 @@ gbinder_ipc_finalize(
}
GASSERT(!g_hash_table_size(priv->tx_table));
g_hash_table_unref(priv->tx_table);
gutil_idle_pool_unref(self->pool);
gbinder_driver_unref(self->driver);
g_free(priv->key);
G_OBJECT_CLASS(gbinder_ipc_parent_class)->finalize(object);
@@ -1795,11 +1783,9 @@ gbinder_ipc_exit()
}
for (k = tx_keys; k; k = k->next) {
GBinderIpcTxPriv* tx = g_hash_table_lookup(priv->tx_table, k->data);
GSource* source = g_source_ref(tx->completion);
GVERBOSE_("tx %lu", tx->pub.id);
g_source_destroy(source);
g_source_unref(source);
gbinder_idle_callback_cancel(tx->completion);
}
/* The above loop must destroy all uncompleted transactions */
@@ -1830,6 +1816,7 @@ gbinder_ipc_exit()
g_slist_free_full(local_objs, g_object_unref);
}
g_slist_free_full(ipcs, g_object_unref);
gbinder_eventloop_set(NULL);
}
/*

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -42,7 +42,6 @@ struct gbinder_ipc {
GObject object;
GBinderIpcPriv* priv;
GBinderDriver* driver;
GUtilIdlePool* pool;
const char* dev;
};
@@ -68,69 +67,68 @@ void
int status,
void* user_data);
G_GNUC_INTERNAL
GBinderIpc*
gbinder_ipc_new(
const char* dev,
const GBinderRpcProtocol* protocol);
const char* dev,
const GBinderRpcProtocol* protocol)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
GBinderIpc*
gbinder_ipc_ref(
GBinderIpc* ipc);
GBinderIpc* ipc)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
void
gbinder_ipc_unref(
GBinderIpc* ipc);
GBinderIpc* ipc)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
void
gbinder_ipc_looper_check(
GBinderIpc* ipc);
GBinderIpc* ipc)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
GBinderObjectRegistry*
gbinder_ipc_object_registry(
GBinderIpc* ipc);
GBinderIpc* ipc)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
void
gbinder_ipc_register_local_object(
GBinderIpc* ipc,
GBinderLocalObject* obj);
GBinderLocalObject* obj)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
GBinderRemoteObject*
gbinder_ipc_get_remote_object(
GBinderIpc* ipc,
guint32 handle,
gboolean maybe_dead);
gboolean maybe_dead)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
void
gbinder_ipc_invalidate_remote_handle(
GBinderIpc* ipc,
guint32 handle);
guint32 handle)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
GBinderRemoteReply*
gbinder_ipc_transact_sync_reply(
GBinderIpc* ipc,
guint32 handle,
guint32 code,
GBinderLocalRequest* req,
int* status);
int* status)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
int
gbinder_ipc_transact_sync_oneway(
GBinderIpc* ipc,
guint32 handle,
guint32 code,
GBinderLocalRequest* req);
GBinderLocalRequest* req)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
gulong
gbinder_ipc_transact(
GBinderIpc* ipc,
@@ -140,43 +138,44 @@ gbinder_ipc_transact(
GBinderLocalRequest* req,
GBinderIpcReplyFunc func,
GDestroyNotify destroy,
void* user_data);
void* user_data)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
gulong
gbinder_ipc_transact_custom(
GBinderIpc* ipc,
GBinderIpcTxFunc exec,
GBinderIpcTxFunc done,
GDestroyNotify destroy,
void* user_data);
void* user_data)
GBINDER_INTERNAL;
G_GNUC_INTERNAL
void
gbinder_ipc_cancel(
GBinderIpc* ipc,
gulong id);
gulong id)
GBINDER_INTERNAL;
/* Internal for GBinderLocalObject */
G_GNUC_INTERNAL
void
gbinder_ipc_local_object_disposed(
GBinderIpc* self,
GBinderLocalObject* obj);
GBinderLocalObject* obj)
GBINDER_INTERNAL;
/* Internal for GBinderRemoteObject */
G_GNUC_INTERNAL
void
gbinder_ipc_remote_object_disposed(
GBinderIpc* self,
GBinderRemoteObject* obj);
GBinderRemoteObject* obj)
GBINDER_INTERNAL;
/* Declared for unit tests */
G_GNUC_INTERNAL
__attribute__((destructor))
void
gbinder_ipc_exit(
void);
void)
GBINDER_INTERNAL;
#endif /* GBINDER_IPC_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -79,7 +79,7 @@ typedef struct gbinder_local_object_class {
/* Need to add some placeholders if this class becomes public */
} GBinderLocalObjectClass;
GType gbinder_local_object_get_type(void);
GType gbinder_local_object_get_type(void) GBINDER_INTERNAL;
#define GBINDER_TYPE_LOCAL_OBJECT (gbinder_local_object_get_type())
#define GBINDER_LOCAL_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GBINDER_TYPE_LOCAL_OBJECT, GBinderLocalObject))
@@ -91,24 +91,28 @@ gulong
gbinder_local_object_add_weak_refs_changed_handler(
GBinderLocalObject* obj,
GBinderLocalObjectFunc func,
void* user_data);
void* user_data)
GBINDER_INTERNAL;
gulong
gbinder_local_object_add_strong_refs_changed_handler(
GBinderLocalObject* obj,
GBinderLocalObjectFunc func,
void* user_data);
void* user_data)
GBINDER_INTERNAL;
void
gbinder_local_object_remove_handler(
GBinderLocalObject* obj,
gulong id);
gulong id)
GBINDER_INTERNAL;
GBINDER_LOCAL_TRANSACTION_SUPPORT
gbinder_local_object_can_handle_transaction(
GBinderLocalObject* self,
const char* iface,
guint code);
guint code)
GBINDER_INTERNAL;
GBinderLocalReply*
gbinder_local_object_handle_transaction(
@@ -116,7 +120,8 @@ gbinder_local_object_handle_transaction(
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status);
int* status)
GBINDER_INTERNAL;
GBinderLocalReply*
gbinder_local_object_handle_looper_transaction(
@@ -124,23 +129,28 @@ gbinder_local_object_handle_looper_transaction(
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status);
int* status)
GBINDER_INTERNAL;
void
gbinder_local_object_handle_increfs(
GBinderLocalObject* obj);
GBinderLocalObject* obj)
GBINDER_INTERNAL;
void
gbinder_local_object_handle_decrefs(
GBinderLocalObject* obj);
GBinderLocalObject* obj)
GBINDER_INTERNAL;
void
gbinder_local_object_handle_acquire(
GBinderLocalObject* obj);
GBinderLocalObject* obj)
GBINDER_INTERNAL;
void
gbinder_local_object_handle_release(
GBinderLocalObject* obj);
GBinderLocalObject* obj)
GBINDER_INTERNAL;
#endif /* GBINDER_LOCAL_OBJECT_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -39,15 +39,18 @@
GBinderLocalReply*
gbinder_local_reply_new(
const GBinderIo* io);
const GBinderIo* io)
GBINDER_INTERNAL;
GBinderOutputData*
gbinder_local_reply_data(
GBinderLocalReply* reply);
GBinderLocalReply* reply)
GBINDER_INTERNAL;
GBinderLocalReply*
gbinder_local_reply_new_from_data(
GBinderBuffer* buffer);
GBinderBuffer* buffer)
GBINDER_INTERNAL;
#endif /* GBINDER_LOCAL_REPLY_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -40,15 +40,18 @@
GBinderLocalRequest*
gbinder_local_request_new(
const GBinderIo* io,
GBytes* init);
GBytes* init)
GBINDER_INTERNAL;
GBinderOutputData*
gbinder_local_request_data(
GBinderLocalRequest* req);
GBinderLocalRequest* req)
GBINDER_INTERNAL;
GBinderLocalRequest*
gbinder_local_request_new_from_data(
GBinderBuffer* buffer);
GBinderBuffer* buffer)
GBINDER_INTERNAL;
#endif /* GBINDER_LOCAL_REQUEST_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -13,9 +13,9 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Jolla Ltd nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -33,17 +33,17 @@
#ifndef GBINDER_LOG_H
#define GBINDER_LOG_H
#include "gbinder_types.h"
#include "gbinder_types_p.h"
#define GLOG_MODULE_NAME GBINDER_LOG_MODULE
#include <gutil_log.h>
/* Declared for unit tests */
G_GNUC_INTERNAL
__attribute__((constructor))
void
gbinder_log_init(
void);
void)
GBINDER_INTERNAL;
#endif /* GBINDER_LOG_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -13,9 +13,9 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Jolla Ltd nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -13,9 +13,9 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Jolla Ltd nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -13,9 +13,9 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Jolla Ltd nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -48,7 +48,8 @@ gbinder_reader_init(
GBinderReader* reader,
GBinderReaderData* data,
gsize offset,
gsize len);
gsize len)
GBINDER_INTERNAL;
#endif /* GBINDER_READER_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -55,15 +55,18 @@ GBinderRemoteObject*
gbinder_remote_object_new(
GBinderIpc* ipc,
guint32 handle,
gboolean maybe_dead);
gboolean maybe_dead)
GBINDER_INTERNAL;
gboolean
gbinder_remote_object_reanimate(
GBinderRemoteObject* obj);
GBinderRemoteObject* obj)
GBINDER_INTERNAL;
void
gbinder_remote_object_handle_death_notification(
GBinderRemoteObject* obj);
GBinderRemoteObject* obj)
GBINDER_INTERNAL;
#endif /* GBINDER_REMOTE_OBJECT_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -39,16 +39,19 @@
GBinderRemoteReply*
gbinder_remote_reply_new(
GBinderObjectRegistry* reg);
GBinderObjectRegistry* reg)
GBINDER_INTERNAL;
void
gbinder_remote_reply_set_data(
GBinderRemoteReply* reply,
GBinderBuffer* buffer);
GBinderBuffer* buffer)
GBINDER_INTERNAL;
gboolean
gbinder_remote_reply_is_empty(
GBinderRemoteReply* reply);
GBinderRemoteReply* reply)
GBINDER_INTERNAL;
#endif /* GBINDER_REMOTE_REPLY_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -46,13 +46,15 @@ gbinder_remote_request_new(
GBinderObjectRegistry* reg,
const GBinderRpcProtocol* protocol,
pid_t pid,
uid_t euid);
uid_t euid)
GBINDER_INTERNAL;
void
gbinder_remote_request_set_data(
GBinderRemoteRequest* request,
guint txcode,
GBinderBuffer* buffer);
GBinderBuffer* buffer)
GBINDER_INTERNAL;
#endif /* GBINDER_REMOTE_REQUEST_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -15,8 +15,8 @@
* documentation and/or other materials provided with the distribution.
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -49,13 +49,14 @@ struct gbinder_rpc_protocol {
char** iface);
};
extern const GBinderRpcProtocol gbinder_rpc_protocol_binder;
extern const GBinderRpcProtocol gbinder_rpc_protocol_hwbinder;
extern const GBinderRpcProtocol gbinder_rpc_protocol_binder GBINDER_INTERNAL;
extern const GBinderRpcProtocol gbinder_rpc_protocol_hwbinder GBINDER_INTERNAL;
/* Returns one of the above based on the device name */
const GBinderRpcProtocol*
gbinder_rpc_protocol_for_device(
const char* dev);
const char* dev)
GBINDER_INTERNAL;
#endif /* GBINDER_RPC_PROTOCOL_H */

View File

@@ -36,13 +36,13 @@
#include "gbinder_client_p.h"
#include "gbinder_local_object_p.h"
#include "gbinder_remote_object_p.h"
#include "gbinder_eventloop_p.h"
#include "gbinder_driver.h"
#include "gbinder_ipc.h"
#include "gbinder_log.h"
#include <gbinder_client.h>
#include <gutil_idlepool.h>
#include <gutil_misc.h>
#include <errno.h>
@@ -62,8 +62,10 @@ struct gbinder_servicemanager_priv {
GHashTable* watch_table;
gulong death_id;
gboolean present;
guint presence_check_id;
GBinderEventLoopTimeout* presence_check;
guint presence_check_delay_ms;
GBinderEventLoopCallback* autorelease_cb;
GSList* autorelease;
};
G_DEFINE_ABSTRACT_TYPE(GBinderServiceManager, gbinder_servicemanager,
@@ -275,9 +277,9 @@ gbinder_servicemanager_reanimated(
{
GBinderServiceManagerPriv* priv = self->priv;
if (priv->presence_check_id) {
g_source_remove(priv->presence_check_id);
priv->presence_check_id = 0;
if (priv->presence_check) {
gbinder_timeout_remove(priv->presence_check);
priv->presence_check = NULL;
}
GINFO("Service manager %s has appeared", self->dev);
/* Re-arm the watches */
@@ -317,13 +319,14 @@ gbinder_servicemanager_presense_check_timer(
gbinder_servicemanager_ref(self);
if (gbinder_remote_object_reanimate(remote)) {
/* Done */
priv->presence_check_id = 0;
priv->presence_check = NULL;
gbinder_servicemanager_reanimated(self);
result = G_SOURCE_REMOVE;
} else if (priv->presence_check_delay_ms < PRESENSE_WAIT_MS_MAX) {
priv->presence_check_delay_ms += PRESENSE_WAIT_MS_STEP;
priv->presence_check_id = g_timeout_add(priv->presence_check_delay_ms,
gbinder_servicemanager_presense_check_timer, self);
priv->presence_check =
gbinder_timeout_add(priv->presence_check_delay_ms,
gbinder_servicemanager_presense_check_timer, self);
result = G_SOURCE_REMOVE;
} else {
result = G_SOURCE_CONTINUE;
@@ -339,9 +342,9 @@ gbinder_servicemanager_presence_check_start(
{
GBinderServiceManagerPriv* priv = self->priv;
GASSERT(!priv->presence_check_id);
GASSERT(!priv->presence_check);
priv->presence_check_delay_ms = PRESENSE_WAIT_MS_MIN;
priv->presence_check_id = g_timeout_add(PRESENSE_WAIT_MS_MIN,
priv->presence_check = gbinder_timeout_add(PRESENSE_WAIT_MS_MIN,
gbinder_servicemanager_presense_check_timer, self);
}
@@ -391,6 +394,20 @@ gbinder_servicemanager_sleep_ms(
(wait.tv_sec > 0 || wait.tv_nsec > 0));
}
static
void
gbinder_servicemanager_autorelease_cb(
gpointer data)
{
GBinderServiceManager* self = GBINDER_SERVICEMANAGER(data);
GBinderServiceManagerPriv* priv = self->priv;
GSList* list = priv->autorelease;
priv->autorelease_cb = NULL;
priv->autorelease = NULL;
g_slist_free_full(list, g_object_unref);
}
/*==========================================================================*
* Internal interface
*==========================================================================*/
@@ -675,10 +692,15 @@ gbinder_servicemanager_get_service_sync(
if (G_LIKELY(self) && name) {
obj = GBINDER_SERVICEMANAGER_GET_CLASS(self)->get_service
(self, name, status);
if (!self->pool) {
self->pool = gutil_idle_pool_new();
if (obj) {
GBinderServiceManagerPriv* priv = self->priv;
priv->autorelease = g_slist_prepend(priv->autorelease, obj);
if (!priv->autorelease_cb) {
priv->autorelease_cb = gbinder_idle_callback_schedule_new
(gbinder_servicemanager_autorelease_cb, self, NULL);
}
}
gutil_idle_pool_add_object(self->pool, obj);
} else if (status) {
*status = (-EINVAL);
}
@@ -915,12 +937,11 @@ gbinder_servicemanager_finalize(
GBinderServiceManager* self = GBINDER_SERVICEMANAGER(object);
GBinderServiceManagerPriv* priv = self->priv;
if (priv->presence_check_id) {
g_source_remove(priv->presence_check_id);
}
gbinder_timeout_remove(priv->presence_check);
gbinder_remote_object_remove_handler(self->client->remote, priv->death_id);
gbinder_idle_callback_destroy(priv->autorelease_cb);
g_slist_free_full(priv->autorelease, g_object_unref);
g_hash_table_destroy(priv->watch_table);
gutil_idle_pool_destroy(self->pool);
gbinder_client_unref(self->client);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -49,7 +49,6 @@ typedef struct gbinder_servicemanager {
GBinderServiceManagerPriv* priv;
const char* dev;
GBinderClient* client;
GUtilIdlePool* pool;
} GBinderServiceManager;
typedef enum gbinder_servicemanager_name_check {
@@ -85,18 +84,20 @@ typedef struct gbinder_servicemanager_class {
void (*unwatch)(GBinderServiceManager* self, const char* name);
} GBinderServiceManagerClass;
GType gbinder_servicemanager_get_type(void);
GType gbinder_servicemanager_get_type(void) GBINDER_INTERNAL;
#define GBINDER_TYPE_SERVICEMANAGER (gbinder_servicemanager_get_type())
GBinderServiceManager*
gbinder_servicemanager_new_with_type(
GType type,
const char* dev);
const char* dev)
GBINDER_INTERNAL;
void
gbinder_servicemanager_service_registered(
GBinderServiceManager* self,
const char* name);
const char* name)
GBINDER_INTERNAL;
#endif /* GBINDER_SERVICEMANAGER_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -32,6 +32,7 @@
#include "gbinder_servicepoll.h"
#include "gbinder_servicemanager.h"
#include "gbinder_eventloop_p.h"
#include <gutil_strv.h>
@@ -46,7 +47,7 @@ struct gbinder_servicepoll {
GBinderServiceManager* manager;
char** list;
gulong list_id;
guint timer_id;
GBinderEventLoopTimeout* timer;
};
G_DEFINE_TYPE(GBinderServicePoll, gbinder_servicepoll, G_TYPE_OBJECT)
@@ -230,7 +231,7 @@ void
gbinder_servicepoll_init(
GBinderServicePoll* self)
{
self->timer_id = g_timeout_add(gbinder_servicepoll_interval_ms,
self->timer = gbinder_timeout_add(gbinder_servicepoll_interval_ms,
gbinder_servicepoll_timer, self);
}
@@ -241,7 +242,7 @@ gbinder_servicepoll_finalize(
{
GBinderServicePoll* self = GBINDER_SERVICEPOLL(object);
g_source_remove(self->timer_id);
gbinder_timeout_remove(self->timer);
gbinder_servicemanager_cancel(self->manager, self->list_id);
gbinder_servicemanager_unref(self->manager);
g_strfreev(self->list);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -35,7 +35,7 @@
#include "gbinder_types_p.h"
extern guint gbinder_servicepoll_interval_ms;
extern guint gbinder_servicepoll_interval_ms GBINDER_INTERNAL;
typedef
void
@@ -47,35 +47,42 @@ void
GBinderServicePoll*
gbinder_servicepoll_new(
GBinderServiceManager* manager,
GBinderServicePoll** weakptr);
GBinderServicePoll** weakptr)
GBINDER_INTERNAL;
GBinderServicePoll*
gbinder_servicepoll_ref(
GBinderServicePoll* poll);
GBinderServicePoll* poll)
GBINDER_INTERNAL;
void
gbinder_servicepoll_unref(
GBinderServicePoll* poll);
GBinderServicePoll* poll)
GBINDER_INTERNAL;
GBinderServiceManager*
gbinder_servicepoll_manager(
GBinderServicePoll* poll);
GBinderServicePoll* poll)
GBINDER_INTERNAL;
gboolean
gbinder_servicepoll_is_known_name(
GBinderServicePoll* poll,
const char* name);
const char* name)
GBINDER_INTERNAL;
gulong
gbinder_servicepoll_add_handler(
GBinderServicePoll* poll,
GBinderServicePollFunc func,
void* user_data);
void* user_data)
GBINDER_INTERNAL;
void
gbinder_servicepoll_remove_handler(
GBinderServicePoll* poll,
gulong id);
gulong id)
GBINDER_INTERNAL;
#endif /* GBINDER_SERVICEPOLL_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -13,9 +13,9 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Jolla Ltd nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -38,29 +38,34 @@
int
gbinder_system_open(
const char* path,
int flags);
int flags)
GBINDER_INTERNAL;
int
gbinder_system_close(
int fd);
int fd)
GBINDER_INTERNAL;
int
gbinder_system_ioctl(
int fd,
int request,
void* data);
void* data)
GBINDER_INTERNAL;
void*
gbinder_system_mmap(
size_t length,
int prot,
int flags,
int fd);
int fd)
GBINDER_INTERNAL;
int
gbinder_system_munmap(
void* addr,
size_t length);
size_t length)
GBINDER_INTERNAL;
#endif /* GBINDER_SYSTEM_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -47,6 +47,7 @@ typedef struct gbinder_servicepoll GBinderServicePoll;
typedef struct gbinder_ipc_looper_tx GBinderIpcLooperTx;
#define GBINDER_INLINE_FUNC static inline
#define GBINDER_INTERNAL G_GNUC_INTERNAL
#define GBINDER_TRANSACTION(c2,c3,c4) GBINDER_FOURCC('_',c2,c3,c4)
#define GBINDER_PING_TRANSACTION GBINDER_TRANSACTION('P','N','G')

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018 Jolla Ltd.
* Copyright (C) 2018 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -14,8 +14,8 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -48,94 +48,111 @@ typedef struct gbinder_writer_data {
void
gbinder_writer_init(
GBinderWriter* writer,
GBinderWriterData* data);
GBinderWriterData* data)
GBINDER_INTERNAL;
void
gbinder_writer_data_set_contents(
GBinderWriterData* data,
GBinderBuffer* buffer);
GBinderBuffer* buffer)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_bool(
GBinderWriterData* data,
gboolean value);
gboolean value)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_int32(
GBinderWriterData* data,
guint32 value);
guint32 value)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_int64(
GBinderWriterData* data,
guint64 value);
guint64 value)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_float(
GBinderWriterData* data,
gfloat value);
gfloat value)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_double(
GBinderWriterData* data,
gdouble value);
gdouble value)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_string8(
GBinderWriterData* data,
const char* str);
const char* str)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_string8_len(
GBinderWriterData* data,
const char* str,
gsize len);
gsize len)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_string16(
GBinderWriterData* data,
const char* utf8);
const char* utf8)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_string16_len(
GBinderWriterData* data,
const char* utf8,
gssize num_bytes);
gssize num_bytes)
GBINDER_INTERNAL;
guint
gbinder_writer_data_append_buffer_object(
GBinderWriterData* data,
const void* ptr,
gsize size,
const GBinderParent* parent);
const GBinderParent* parent)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_hidl_vec(
GBinderWriterData* data,
const void* base,
guint count,
guint elemsize);
guint elemsize)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_hidl_string(
GBinderWriterData* data,
const char* str);
const char* str)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_hidl_string_vec(
GBinderWriterData* data,
const char* strv[],
gssize count);
gssize count)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_local_object(
GBinderWriterData* data,
GBinderLocalObject* obj);
GBinderLocalObject* obj)
GBINDER_INTERNAL;
void
gbinder_writer_data_append_remote_object(
GBinderWriterData* data,
GBinderRemoteObject* obj);
GBinderRemoteObject* obj)
GBINDER_INTERNAL;
#endif /* GBINDER_WRITER_PRIVATE_H */

View File

@@ -6,6 +6,7 @@ all:
@$(MAKE) -C unit_cleanup $*
@$(MAKE) -C unit_client $*
@$(MAKE) -C unit_driver $*
@$(MAKE) -C unit_eventloop $*
@$(MAKE) -C unit_ipc $*
@$(MAKE) -C unit_local_object $*
@$(MAKE) -C unit_local_reply $*

View File

@@ -8,6 +8,7 @@ unit_buffer \
unit_cleanup \
unit_client \
unit_driver \
unit_eventloop \
unit_ipc \
unit_local_object \
unit_local_reply \

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -75,10 +75,13 @@ test_null(
void)
{
g_assert(!gbinder_client_new(NULL, NULL));
g_assert(!gbinder_client_new2(NULL, NULL, 0));
g_assert(!gbinder_client_ref(NULL));
g_assert(!gbinder_client_interface(NULL));
g_assert(!gbinder_client_interface2(NULL, 0));
gbinder_client_unref(NULL);
g_assert(!gbinder_client_new_request(NULL));
g_assert(!gbinder_client_new_request2(NULL, 0));
g_assert(!gbinder_client_transact_sync_reply(NULL, 0, NULL, NULL));
g_assert(gbinder_client_transact_sync_oneway(NULL, 0, NULL) == (-EINVAL));
g_assert(!gbinder_client_transact(NULL, 0, 0, NULL, NULL, NULL, NULL));
@@ -102,7 +105,7 @@ test_basic(
g_assert(client);
g_assert(gbinder_client_ref(client) == client);
g_assert(!g_strcmp0(gbinder_client_interface(client), iface));
g_assert_cmpstr(gbinder_client_interface(client), == ,iface);
gbinder_client_unref(client);
gbinder_client_cancel(client, 0); /* does nothing */
@@ -111,6 +114,44 @@ test_basic(
gbinder_ipc_unref(ipc);
}
/*==========================================================================*
* interfaces
*==========================================================================*/
static
void
test_interfaces(
void)
{
GBinderIpc* ipc = gbinder_ipc_new(GBINDER_DEFAULT_BINDER, NULL);
GBinderObjectRegistry* reg = gbinder_ipc_object_registry(ipc);
GBinderRemoteObject* obj = gbinder_object_registry_get_remote(reg, 0);
static const GBinderClientIfaceInfo ifaces[] = {
{"33", 33 }, { "11", 11 }, { "22", 22 }
};
GBinderClient* client = gbinder_client_new2(obj, ifaces,
G_N_ELEMENTS(ifaces));
g_assert(client);
g_assert_cmpstr(gbinder_client_interface(client), == ,"11");
g_assert_cmpstr(gbinder_client_interface2(client, 11), == ,"11");
g_assert_cmpstr(gbinder_client_interface2(client, 22), == ,"22");
g_assert_cmpstr(gbinder_client_interface2(client, 33), == ,"33");
g_assert(!gbinder_client_interface2(client, 34));
g_assert(!gbinder_client_new_request2(client, 34));
gbinder_client_unref(client);
/* Client with no interface info */
client = gbinder_client_new2(obj, NULL, 0);
g_assert(client);
g_assert(!gbinder_client_interface(client));
g_assert(!gbinder_client_interface2(client, 1));
gbinder_client_unref(client);
gbinder_remote_object_unref(obj);
gbinder_ipc_unref(ipc);
}
/*==========================================================================*
* no_header
*==========================================================================*/
@@ -344,8 +385,9 @@ test_reply(
GDestroyNotify destroy)
{
GBinderClient* client = test_client_new(0, TEST_INTERFACE);
GBinderLocalRequest* req = gbinder_client_new_request(client);
GBinderLocalRequest* req = gbinder_client_new_request2(client, 0);
g_assert(req);
test_reply_tx(client, req, done, destroy);
gbinder_local_request_unref(req);
@@ -391,6 +433,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_("interfaces"), test_interfaces);
g_test_add_func(TEST_("dead"), test_dead);
g_test_add_func(TEST_("no_header"), test_no_header);
g_test_add_func(TEST_("sync_oneway"), test_sync_oneway);

View File

@@ -0,0 +1,5 @@
# -*- Mode: makefile-gmake -*-
EXE = unit_eventloop
include ../common/Makefile

View File

@@ -0,0 +1,262 @@
/*
* Copyright (C) 2020 Jolla Ltd.
* Copyright (C) 2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test_common.h"
#include "gbinder_eventloop_p.h"
static TestOpt test_opt;
static int test_eventloop_timeout_add_called;
static int test_eventloop_callback_new_called;
static int test_eventloop_cleanup_called;
static
gboolean
test_unreached_proc(
gpointer data)
{
g_assert_not_reached();
return G_SOURCE_CONTINUE;
}
/*==========================================================================*
* Test event loop integration
*==========================================================================*/
static
GBinderEventLoopTimeout*
test_eventloop_timeout_add(
guint interval,
GSourceFunc func,
gpointer data)
{
test_eventloop_timeout_add_called++;
return NULL;
}
static
void
test_eventloop_timeout_remove(
GBinderEventLoopTimeout* timeout)
{
g_assert_not_reached();
}
static
GBinderEventLoopCallback*
test_eventloop_callback_new(
GBinderEventLoopCallbackFunc func,
gpointer data,
GDestroyNotify destroy)
{
test_eventloop_callback_new_called++;
return NULL;
}
static
void
test_eventloop_callback_ref(
GBinderEventLoopCallback* cb)
{
g_assert_not_reached();
}
static
void
test_eventloop_callback_unref(
GBinderEventLoopCallback* cb)
{
g_assert_not_reached();
}
static
void
test_eventloop_callback_schedule(
GBinderEventLoopCallback* cb)
{
g_assert_not_reached();
}
static
void
test_eventloop_callback_cancel(
GBinderEventLoopCallback* cb)
{
g_assert_not_reached();
}
static
void
test_eventloop_cleanup(
void)
{
test_eventloop_cleanup_called++;
}
static const GBinderEventLoopIntegration test_eventloop = {
test_eventloop_timeout_add,
test_eventloop_timeout_remove,
test_eventloop_callback_new,
test_eventloop_callback_ref,
test_eventloop_callback_unref,
test_eventloop_callback_schedule,
test_eventloop_callback_cancel,
test_eventloop_cleanup
};
/*==========================================================================*
* replace
*==========================================================================*/
static
void
test_replace(
void)
{
test_eventloop_timeout_add_called = 0;
test_eventloop_callback_new_called = 0;
test_eventloop_cleanup_called = 0;
gbinder_eventloop_set(NULL);
gbinder_eventloop_set(&test_eventloop);
g_assert(!gbinder_timeout_add(0, test_unreached_proc, NULL));
g_assert_cmpint(test_eventloop_timeout_add_called, == ,1);
g_assert(!gbinder_idle_add(test_unreached_proc, NULL));
g_assert_cmpint(test_eventloop_timeout_add_called, == ,2);
gbinder_timeout_remove(NULL);
g_assert(!gbinder_idle_callback_new(NULL, NULL, NULL));
g_assert_cmpint(test_eventloop_callback_new_called, == ,1);
g_assert(!gbinder_idle_callback_ref(NULL));
gbinder_idle_callback_unref(NULL);
gbinder_idle_callback_schedule(NULL);
gbinder_idle_callback_cancel(NULL);
gbinder_eventloop_set(NULL);
g_assert_cmpint(test_eventloop_cleanup_called, == ,1);
}
/*==========================================================================*
* idle
*==========================================================================*/
static
gboolean
test_quit_func(
gpointer data)
{
g_main_loop_quit((GMainLoop*)data);
return G_SOURCE_REMOVE;
}
static
void
test_idle(
void)
{
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gbinder_eventloop_set(NULL);
g_assert(gbinder_idle_add(test_quit_func, loop));
test_run(&test_opt, loop);
g_main_loop_unref(loop);
}
/*==========================================================================*
* timeout
*==========================================================================*/
static
void
test_timeout(
void)
{
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
gbinder_eventloop_set(NULL);
g_assert(gbinder_timeout_add(10, test_quit_func, loop));
test_run(&test_opt, loop);
g_main_loop_unref(loop);
}
/*==========================================================================*
* callback
*==========================================================================*/
static
void
test_quit_cb(
gpointer data)
{
g_main_loop_quit((GMainLoop*)data);
}
static
void
test_callback(
void)
{
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
GBinderEventLoopCallback* cb;
gbinder_eventloop_set(NULL);
cb = gbinder_idle_callback_new(test_quit_cb, loop, NULL);
gbinder_idle_callback_schedule(cb);
test_run(&test_opt, loop);
gbinder_idle_callback_unref(cb);
g_main_loop_unref(loop);
}
/*==========================================================================*
* Common
*==========================================================================*/
#define TEST_(t) "/eventloop/" t
int main(int argc, char* argv[])
{
g_test_init(&argc, &argv, NULL);
g_test_add_func(TEST_("replace"), test_replace);
g_test_add_func(TEST_("idle"), test_idle);
g_test_add_func(TEST_("timeout"), test_timeout);
g_test_add_func(TEST_("callback"), test_callback);
test_init(&test_opt, argc, argv);
return g_test_run();
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/