diff --git a/configure.ac b/configure.ac index ec9f9be..9b23c12 100644 --- a/configure.ac +++ b/configure.ac @@ -81,7 +81,7 @@ AM_CONDITIONAL(HAVE_GTKMM, test 0 = 1) fi AC_CHECK_LIB([expat], XML_ParserCreate_MM, - [ AC_CHECK_HEADERS(expat.h, have_expat=true, have_expat=false) ], + [AC_CHECK_HEADERS(expat.h, have_expat=true, have_expat=false)], have_expat=false) if ! $have_expat; then @@ -95,6 +95,12 @@ xml_LIBS=-lexpat AC_SUBST(xml_CFLAGS) AC_SUBST(xml_LIBS) +AC_CHECK_LIB([pthread], pthread_create, + [AC_CHECK_HEADERS(pthread.h, have_pthread=true, have_pthread=false)], + have_pthread=false) + +AM_CONDITIONAL(HAVE_PTHREAD, test x$have_pthread = xtrue) + if test x$enable_debug = xyes ; then CXXFLAGS="-Wall -ggdb -O0 -DDEBUG" else diff --git a/examples/echo/Makefile.am b/examples/echo/Makefile.am index b9b861c..d3d8e56 100644 --- a/examples/echo/Makefile.am +++ b/examples/echo/Makefile.am @@ -4,13 +4,23 @@ AM_CPPFLAGS = -I$(top_srcdir)/include noinst_PROGRAMS = echo-server -echo_server_SOURCES = echo-glue.h echo-server.h echo-server.cpp +echo_server_SOURCES = echo-server-glue.h echo-server.h echo-server.cpp echo_server_LDADD = $(top_builddir)/src/libdbus-c++-1.la -echo-glue.h: echo-introspect.xml +echo-server-glue.h: echo-introspect.xml $(top_builddir)/tools/dbusxx-xml2cpp $^ --adaptor=$@ -BUILT_SOURCES = echo-glue.h +if HAVE_PTHREAD +noinst_PROGRAMS += echo-client-mt +endif + +echo_client_mt_SOURCES = echo-client-glue.h echo-client.h echo-client.cpp +echo_client_mt_LDADD = $(top_builddir)/src/libdbus-c++-1.la -lpthread + +echo-client-glue.h: echo-introspect.xml + $(top_builddir)/tools/dbusxx-xml2cpp $^ --proxy=$@ + +BUILT_SOURCES = echo-server-glue.h echo-client-glue.h CLEANFILES = $(BUILT_SOURCES) dist-hook: diff --git a/examples/echo/echo-client.cpp b/examples/echo/echo-client.cpp new file mode 100644 index 0000000..a242294 --- /dev/null +++ b/examples/echo/echo-client.cpp @@ -0,0 +1,80 @@ +#include "echo-client.h" +#include +#include +#include + +using namespace std; + +static const char* ECHO_SERVER_NAME = "org.freedesktop.DBus.Examples.Echo"; +static const char* ECHO_SERVER_PATH = "/org/freedesktop/DBus/Examples/Echo"; + +EchoClient::EchoClient( DBus::Connection& connection, const char* path, const char* name ) +: DBus::ObjectProxy(connection, path, name) +{ +} + +void EchoClient::Echoed( const DBus::Variant& value ) +{ + cout << "!"; +} + +/* NOTE: using many threads is likely to trigger a race condition in the event loop + * in fact access to the list of timeouts and watches inside the default dispatcher + * implementation (DBus::BusDispatcher) is NOT serialized + * + * (yes, I'm well aware of how much this sucks) + */ +static const int THREADS = 1; + +static bool spin = true; + +void* greeter_thread( void* ) +{ + DBus::Connection conn = DBus::Connection::SessionBus(); + + EchoClient client(conn, ECHO_SERVER_PATH, ECHO_SERVER_NAME); + + while(spin) + { + client.Hello("client"); + + cout << "*"; + } + + return NULL; +} + +DBus::BusDispatcher dispatcher; + +void niam( int sig ) +{ + spin = false; + + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::_init_threading(); + + DBus::default_dispatcher = &dispatcher; + + pthread_t threads[THREADS]; + + for(int i = 0; i < THREADS; ++i) + { + pthread_create(threads+i, NULL, greeter_thread, NULL); + } + + dispatcher.enter(); + + for(int i = 0; i < THREADS; ++i) + { + pthread_join(threads[i], NULL); + } + + return 0; +} diff --git a/examples/echo/echo-client.h b/examples/echo/echo-client.h new file mode 100644 index 0000000..0f88e80 --- /dev/null +++ b/examples/echo/echo-client.h @@ -0,0 +1,19 @@ +#ifndef __DEMO_ECHO_CLIENT_H +#define __DEMO_ECHO_CLIENT_H + +#include +#include "echo-client-glue.h" + +class EchoClient +: public org::freedesktop::DBus::EchoDemo, + public DBus::IntrospectableProxy, + public DBus::ObjectProxy +{ +public: + + EchoClient( DBus::Connection& connection, const char* path, const char* name ); + + void Echoed( const DBus::Variant& value ); +}; + +#endif//__DEMO_ECHO_CLIENT_H diff --git a/examples/echo/echo-server.h b/examples/echo/echo-server.h index d1007ac..989d84c 100644 --- a/examples/echo/echo-server.h +++ b/examples/echo/echo-server.h @@ -2,7 +2,7 @@ #define __DEMO_ECHO_SERVER_H #include -#include "echo-glue.h" +#include "echo-server-glue.h" class EchoServer : public org::freedesktop::DBus::EchoDemo, diff --git a/include/dbus-c++/config.h.in b/include/dbus-c++/config.h.in index 8130122..e02365b 100644 --- a/include/dbus-c++/config.h.in +++ b/include/dbus-c++/config.h.in @@ -18,6 +18,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H diff --git a/include/dbus-c++/connection.h b/include/dbus-c++/connection.h index 62a95b9..028ab85 100644 --- a/include/dbus-c++/connection.h +++ b/include/dbus-c++/connection.h @@ -91,6 +91,8 @@ public: void disconnect(); + void exit_on_disconnect( bool exit ); + void flush(); bool send( const Message&, unsigned int* serial = NULL ); diff --git a/include/dbus-c++/dispatcher.h b/include/dbus-c++/dispatcher.h index c59ec6c..a613735 100644 --- a/include/dbus-c++/dispatcher.h +++ b/include/dbus-c++/dispatcher.h @@ -181,6 +181,8 @@ typedef bool (*CondVarWaitTimeoutFn)( CondVar* cv, Mutex* mx, int timeout ); typedef void (*CondVarWakeOneFn)( CondVar* cv ); typedef void (*CondVarWakeAllFn)( CondVar* cv ); +void _init_threading(); + void _init_threading( MutexNewFn, MutexFreeFn, MutexLockFn, MutexUnlockFn, CondVarNewFn, CondVarFreeFn, CondVarWaitFn, CondVarWaitTimeoutFn, CondVarWakeOneFn, CondVarWakeAllFn diff --git a/src/connection.cpp b/src/connection.cpp index 4f7369a..e961d0d 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -282,6 +282,11 @@ void Connection::disconnect() dbus_connection_close(_pvt->conn); } +void Connection::exit_on_disconnect( bool exit ) +{ + dbus_connection_set_exit_on_disconnect(_pvt->conn, exit); +} + bool Connection::unique_name( const char* n ) { return dbus_bus_set_unique_name(_pvt->conn, n); diff --git a/src/dispatcher.cpp b/src/dispatcher.cpp index c8100df..f0f5293 100644 --- a/src/dispatcher.cpp +++ b/src/dispatcher.cpp @@ -168,6 +168,11 @@ void Dispatcher::dispatch_pending() } } +void DBus::_init_threading() +{ + dbus_threads_init_default(); +} + void DBus::_init_threading( MutexNewFn m1, MutexFreeFn m2,