Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

src/DbusConnection.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Traplas visualisation.
00004 
00005 Copyright (C) 2006 Herbert de Vos & Willem Drost
00006 
00007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00010 
00011 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00012 
00013 (For full Licence see ../GPL-Licence.txt)
00014 
00015 */
00016 
00020 #define ASYNCHRONOUS 0
00021 #define SYNCHRONOUS 1
00022 
00023 #ifndef DBUSCONNECTION_H
00024 #include "DbusConnection.h"
00025 #endif
00026 
00027 #ifndef MESSAGECONTROLLER_H
00028 #include "MessageController.h"
00029 #endif
00030 
00031 GType some_object_get_type (void);
00032 G_DEFINE_TYPE(SomeObject, some_object, G_TYPE_OBJECT)
00033 gboolean _send_message(SomeObject* obj, char** messgArray, GError** wrong);
00034 
00035 #include "DbusConnection-glue.h"
00036 
00037 static void
00038 some_object_init (SomeObject *)
00039 {
00040 }
00041 
00042 static void
00043 some_object_class_init (SomeObjectClass *)
00044 {
00045 }
00046 
00047 static void
00048 lose (const char *str, ...)
00049 {
00050   va_list args;
00051 
00052   va_start (args, str);
00053 
00054   vfprintf (stderr, str, args);
00055   fputc ('\n', stderr);
00056 
00057   va_end (args);
00058 
00059   exit (1);
00060 }
00061 
00062 static void
00063 lose_gerror (const char *prefix, GError *error)
00064 {
00065   lose ("%s: %s", prefix, error->message);
00066 }
00067 
00068 /*
00069  * Our sendMessage function: Used to process messages.
00070  */
00071 gboolean _send_message(SomeObject* obj, char** messgArray, GError** ) {
00072         MessageController* myc = obj->mc;
00073 
00074         //      Construct the message.
00075         shared_ptr< vector< shared_ptr< string > > > message( new vector< shared_ptr< string > >() );
00076         for ( int i = 0 ; messgArray[i] != NULL ; i++) {
00077                 shared_ptr< string > newword( new string( messgArray[i] ) );
00078                 message->push_back(newword);
00079         }
00080 
00081         //      Now send the message to the MessageController.
00082         myc-> processMessageFromComm( message );
00083 
00084         return TRUE;
00085 }
00086 
00087 /*
00088  *      The receive-thread contains the glib_main_loop for receiving messages.
00089  */
00090 void* receiveThread(void* mainloop) {
00091 
00092         g_main_loop_run((GMainLoop*)mainloop);
00093 
00094         return 0;
00095 }
00096 
00097 /*
00098  *      The send-thread. It looks at the outqueue for messages to be send.
00099  */
00100 void* sendThread(void* att) {
00101 
00102         GError *error = NULL;
00103 
00104         DbusConnection* myconnection = (DbusConnection*) att;
00105         bool message_ready;
00106 
00107         while ( myconnection->sendthread_run ) {
00108                 if ( pthread_mutex_trylock( &(myconnection->mutex) ) != 0 )
00109                         pthread_cond_wait( &(myconnection->cond), &(myconnection->mutex) );
00110 
00111                 char **sendArray = NULL;
00112 
00113                 if (!myconnection->outqueue->empty()) {
00114                         //      Construct the message to be sent over Dbus and clean up.
00115                         ostringstream msg;
00116 
00117                         vector< shared_ptr< string > >::iterator iter;
00118                         iter = myconnection->outqueue->front()->begin();
00119                         while ( iter != myconnection->outqueue->front()->end() ) {
00120                                 msg << **iter << " ";
00121                                 iter++;
00122                         }
00123 
00124                         sendArray = g_strsplit(msg.str().c_str(), " ", 0);
00125 
00126                         myconnection->outqueue->pop();
00127                         message_ready = true;
00128                 } else message_ready = false;
00129                 pthread_mutex_unlock( &(myconnection->mutex) );
00130                 pthread_cond_signal( &(myconnection->cond) );
00131 
00132                 if ( message_ready ) {
00133                         #if SYNCHRONOUS
00134 
00135                         if(!dbus_g_proxy_call(  myconnection->remote_object,
00136                                                                         "SendMessage",
00137                                                                         &error,
00138                                                                         G_TYPE_STRV,
00139                                                                         sendArray,
00140                                                                         G_TYPE_INVALID,
00141                                                                         G_TYPE_INVALID)) {
00142                                 lose_gerror ("failed to send message", error);
00143                         } 
00144                         #endif
00145 
00146                         #if ASYNCHRONOUS
00147                         DBusGProxyCall* callID;
00148 
00149                         callID = dbus_g_proxy_begin_call(       myconnection->remote_object,
00150                                                                                                 "SendMessage",
00151                                                                                                 NULL ,
00152                                                                                                 NULL,
00153                                                                                                 NULL ,
00154                                                                                                 G_TYPE_STRV,
00155                                                                                                 sendArray,
00156                                                                                                 G_TYPE_INVALID);
00157 
00158 
00159                         if(!dbus_g_proxy_end_call(      myconnection->remote_object,
00160                                                                                 callID,
00161                                                                                 &error,
00162                                                                                 G_TYPE_INVALID)) {
00163                                 lose_gerror("failed to send message",error);
00164                         } 
00165                         #endif
00166 
00167                         g_strfreev(sendArray);
00168                 } else
00169                         usleep(50);     //No messages left in the queue, check again later.             
00170         }
00171         int status = 0;
00172         pthread_exit(&status);
00173 }
00174 
00175 //      ---------------------------------------------------------------------------------------------
00176 //      DbusConnection code.
00177 
00178 void DbusConnection::dbus_init() {
00179         //      Initialise Dbus
00180 
00181         g_type_init ();
00182 
00183         DBusGConnection *bus;
00184         DBusGProxy *bus_proxy;
00185         GError *error = NULL;
00186 
00187         bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
00188         if (!bus)
00189                 lose_gerror ("Couldn't connect to session bus.", error);
00190 
00191         SomeObject *obj;
00192         guint request_name_result;
00193 
00194         mainloop = g_main_loop_new (NULL, FALSE);
00195 
00196         dbus_g_object_type_install_info (SOME_TYPE_OBJECT, &dbus_glib__object_info);
00197 
00198         char otherName[512]="some.";
00199         strcat(otherName, thatapp.c_str());
00200         remote_object = dbus_g_proxy_new_for_name (     bus,
00201                                                                                                 otherName,
00202                                                                                                 "/SomeObject",
00203                                                                                                 "some.SampleInterface");
00204 
00205         bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus",
00206                                 "/org/freedesktop/DBus",
00207                                 "org.freedesktop.DBus");
00208 
00209         char registerName[512]="some.";
00210         strcat(registerName, thisapp.c_str());
00211         if (!dbus_g_proxy_call (bus_proxy, "RequestName", &error,
00212                                 G_TYPE_STRING, registerName,
00213                                 G_TYPE_UINT, 0,
00214                                 G_TYPE_INVALID,
00215                                 G_TYPE_UINT, &request_name_result,
00216                                 G_TYPE_INVALID))
00217                 lose_gerror ("Failed to acquire that name.\n", error);
00218 
00219         obj = (SomeObject*)g_object_new (SOME_TYPE_OBJECT, NULL);
00220         obj->mc = msgcontroller;
00221 
00222         dbus_g_connection_register_g_object (bus, "/SomeObject", G_OBJECT (obj));
00223 }
00224 
00225 DbusConnection::DbusConnection(string nthisapp, string nthatapp, MessageController* ptr) {
00226 
00227         thisapp = nthisapp;
00228         thatapp = nthatapp;
00229         msgcontroller = ptr;
00230 
00231         sendthread_run = true;
00232 
00233         //      Construct the queue and mutex&condition variables and init them.
00234         outqueue = shared_ptr< queue< shared_ptr< vector< shared_ptr<string> > > > >( new queue< shared_ptr< vector< shared_ptr<string> > > >() );
00235         pthread_mutex_init(&mutex, NULL);       
00236         pthread_cond_init(&cond, NULL); 
00237 
00238         //      Initialise Dbus
00239         dbus_init();
00240 
00241         //      Starting receiving thread.
00242         pthread_create(&receivethread, NULL, receiveThread, (void*) mainloop);
00243 
00244         //      Starting sending thread. This thread processes the outqueue.
00245         pthread_create(&sendthread, NULL, sendThread, (void*)this);
00246 }
00247 
00248 DbusConnection::~DbusConnection() {
00249         //TODO  Destructor not tested.
00250 
00251         //      Signal the senthread to quit
00252         sendthread_run = false;
00253 
00254         //      Kill the glib_mainloop
00255         g_main_destroy(mainloop);
00256         
00257         g_object_unref (G_OBJECT (remote_object));
00258         
00259         //      Wait for the threads to finish.
00260         pthread_join( sendthread, NULL);
00261         pthread_join( receivethread, NULL);             
00262 }
00263 
00264 bool DbusConnection::sendMessage(shared_ptr< vector< shared_ptr< string > > > messagebody) {
00265         //      Put a message in the outgoing queue.
00266 
00267         if ( pthread_mutex_trylock(&mutex) != 0 )
00268                 pthread_cond_wait(&cond, &mutex);
00269 
00270         outqueue->push(messagebody);
00271 
00272         pthread_mutex_unlock(&mutex);
00273         pthread_cond_signal(&cond);
00274         
00275         return true;
00276 }

Generated on Mon Jun 19 10:22:04 2006 for TraplasVisualisation by  doxygen 1.4.4