I have a problem with Dbus-Glib

MeduZa meduzapat at netscape.net
Tue Jan 27 14:19:05 PST 2009


Hello, I'm new programing on Dbus and Glib, I made a plug in for a 
project that I'm working on, to read the battery levels and state, this 
is my first time using this libraries.
The program works perfectly except that when it runs it starts eating 
memory (something like 16Kb each time the FOR executes) on the 
dbus_g_proxy_call command.

I checked to see if maybe I forgot to free something or maybe I 
implemented the command in the wrong way but I can't find the memory leak.

Here is the code:

//   battery.cpp
//  Thu Jan 15 18:47:27 2009
//  Copyright  2009  MeduZa
// <meduzapat at netscape.net>

//battery libraries
#include <iostream>
#include <sstream>
#include <vector>
#include <dbus/dbus-glib.h>
#include "system.hpp"

#define TOTAL_ITEMS 5      //total Items

/*********************************
  *       Variables Globales      *
  *********************************/
bool loaded = false;        //flag plugin loaded
int totalbaterias;        //batteries count

struct bateria{
     string udi;        //udi
     string nombre;        //info.product
     string tipo;        //battery.type
     string tecnologia;    //battery.technology not allwais available
     int carga;        //last_full-current
     string estado;        //if present , is chargable > is chargin / 
dischargin , N/A
};

vector<bateria> Tabla_Baterias;

/*********************************
  *        Funciones Ayuda        *
  *********************************/

int leeindice(string &udi){
     if(loaded){
         int conta;
         for(conta = 0;conta < totalbaterias ; conta ++)    if(udi == 
Tabla_Baterias[conta].udi) break;
         if(conta < totalbaterias) return conta;
     }
     return -1;
}

static DBusGProxy * get_dbus_proxy(const string &destino,const string 
&objpath,const string &iface){
     g_return_val_if_fail (destino.c_str() && objpath.c_str() && 
iface.c_str(), NULL);
     DBusGConnection *connection;
     DBusGProxy *proxy = NULL;
     GError *el_error = NULL;
     connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &el_error );
     if(connection != NULL){
         proxy = dbus_g_proxy_new_for_name(connection,destino.c_str(), 
objpath.c_str(), iface.c_str());
     }else g_warning("Failed to open connection to bus: %s",(el_error && 
el_error ->message) ? el_error ->message : "(unknown error)");
     if (el_error  != NULL) g_error_free(el_error );
     if (connection != NULL) dbus_g_connection_unref(connection);
     return proxy;
}

static gboolean error_happened(gboolean code, GError *es_error){
     g_return_val_if_fail(code || es_error != NULL, true);
     gboolean retval = false;
     if(!code){
         #ifdef DEBUG
             if(es_error->domain == DBUS_GERROR && es_error->code == 
DBUS_GERROR_REMOTE_EXCEPTION)
                 g_warning("Caught remote method exception %s: %s", 
dbus_g_error_get_name (es_error),es_error->message);
             else{
                 g_warning("Error: (%d) %s",
                 es_error->code, es_error->message);
             }
         #endif
         retval = true;
     }
     if(es_error != NULL) g_error_free(es_error);
     return retval;
}

bool leetodo(bateria &Bateria,gboolean lnombres,gboolean 
lcharge,gboolean lestado){
     GError *el_error = NULL;
     gboolean result;
     DBusGProxy *proxy = NULL;
     proxy = get_dbus_proxy("org.freedesktop.Hal", Bateria.udi.c_str(), 
"org.freedesktop.Hal.Device");
     if(lnombres){
         char *nombre, *tipo, *tecnologia;    //strings pointers for 
text data << need free
         result = dbus_g_proxy_call(proxy, "GetProperty", &el_error, 
G_TYPE_STRING, "info.product", G_TYPE_INVALID, G_TYPE_STRING, &nombre, 
G_TYPE_INVALID);
         if(error_happened(result, el_error)) Bateria.nombre = "N/A";
         else{
             Bateria.nombre = nombre;
             g_free(nombre);
         }
         el_error = NULL;
         result = dbus_g_proxy_call(proxy, "GetPropertyString", 
&el_error, G_TYPE_STRING, "battery.type",G_TYPE_INVALID, G_TYPE_STRING, 
&tipo, G_TYPE_INVALID);
         if(error_happened(result, el_error)) Bateria.tipo = "N/A";
         else{
             Bateria.tipo = tipo;
             g_free(tipo);
         }
         el_error = NULL;
         result = dbus_g_proxy_call(proxy, "GetProperty", &el_error, 
G_TYPE_STRING, "battery.reporting.technology", G_TYPE_INVALID, 
G_TYPE_STRING, &tecnologia, G_TYPE_INVALID);
         if(error_happened(result, el_error)) Bateria.tecnologia = "N/A";
         else{
             Bateria.tecnologia = tecnologia;
             g_free(tecnologia);
         }
     }
     if(lcharge){
         gint ultima, ahora;
         Bateria.carga  = 0;
         el_error = NULL;
         result = dbus_g_proxy_call(proxy, "GetProperty", &el_error, 
G_TYPE_STRING, "battery.charge_level.last_full", G_TYPE_INVALID, 
G_TYPE_INT, &ultima, G_TYPE_INVALID);
         if(!error_happened(result, el_error)){
             el_error = NULL;
             result = dbus_g_proxy_call(proxy, "GetProperty", &el_error, 
G_TYPE_STRING, "battery.charge_level.current",G_TYPE_INVALID, 
G_TYPE_INT, &ahora, G_TYPE_INVALID);
             if(!error_happened(result, el_error)){
                 if(ultima < 1) ultima = 1;
                 Bateria.carga = (ahora*100 / ultima*100) /100;
             }
         }
     }
     if(lestado){
         gboolean presente, recargable, cargando, descargando;
         el_error = NULL;
         result = dbus_g_proxy_call(proxy, "GetProperty", &el_error, 
G_TYPE_STRING, "battery.present",G_TYPE_INVALID, G_TYPE_BOOLEAN, 
&presente,G_TYPE_INVALID);
         if(!error_happened(result, el_error)){
             if(!presente) Bateria.estado  = "Missing";
             else{
                 el_error = NULL;
                 result = dbus_g_proxy_call(proxy, "GetProperty", 
&el_error, G_TYPE_STRING, "battery.is_rechargeable",G_TYPE_INVALID, 
G_TYPE_BOOLEAN, &recargable,G_TYPE_INVALID);
                 if(!error_happened(result, el_error)){
                     if(!recargable)    Bateria.estado  = "Ready";
                     else{
                         el_error = NULL;
                         result = dbus_g_proxy_call(proxy, 
"GetProperty", &el_error, G_TYPE_STRING, 
"battery.rechargeable.is_charging",G_TYPE_INVALID, G_TYPE_BOOLEAN, 
&cargando,G_TYPE_INVALID);
                         if(!error_happened(result, el_error)){
                             if(cargando) Bateria.estado  = "Charging";
                             else{
                                 el_error = NULL;
                                 result = dbus_g_proxy_call(proxy, 
"GetProperty", &el_error, G_TYPE_STRING, 
"battery.rechargeable.is_discharging",G_TYPE_INVALID, G_TYPE_BOOLEAN, 
&descargando, G_TYPE_INVALID);
                                 if(!error_happened(result, el_error)){
                                     if(descargando) Bateria.estado  = 
"Working";
                                     else Bateria.estado  = "Ready";
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     if (proxy != NULL) g_object_unref(proxy);
     return true;
}

/*********************************
  *      Funciones Externas       *
  *********************************/

int Init(){        //returns total Items and try to init the plugin 
return -1 on fail
     if(!loaded){
         char **name_list;                //udi list names
         char **name_list_ptr;                //poiner for list names
         bateria Bateria_temp;                //temp bateria
         DBusGProxy *proxy;                //proxy handler
         GError *el_error = NULL;            //error handler
         gboolean resultado;                //result
         g_type_init ();                    //init g
         #ifdef DEBUG
             cout << "Internal plugin Data Initiation..." << endl;
         #endif
         //variables that need 2be started
         proxy = get_dbus_proxy("org.freedesktop.Hal", 
"/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager");
         if(proxy == NULL) return -1;
         #ifdef DEBUG
             cout << "Connection to the bus success" << endl;
         #endif
         resultado = dbus_g_proxy_call(proxy, "FindDeviceByCapability", 
&el_error, G_TYPE_STRING, "battery", G_TYPE_INVALID, G_TYPE_STRV, 
&name_list, G_TYPE_INVALID);
         if(error_happened(resultado, el_error))    return -1;
         #ifdef DEBUG
             cout << "Proxy success, getting data..." << endl;
         #endif
         g_object_unref(proxy);
         for (name_list_ptr = name_list,totalbaterias = 0; 
*name_list_ptr; name_list_ptr++,totalbaterias ++){
             #ifdef DEBUG
                 cout << "Getting Battery " << totalbaterias << " Data" 
<< endl;
             #endif
             Bateria_temp.udi = *name_list_ptr;
             leetodo(Bateria_temp,true,true,true);
             Tabla_Baterias.push_back(Bateria_temp);
         }
         g_strfreev (name_list);
         loaded = true;
         return TOTAL_ITEMS;
     }
}

string Get_Value(int index,string& udi){
     int indice = leeindice(udi);
     switch (index){
         case 0:return "N/A";
         break;                    //error return
         case 1:{                //funcion 1 Battery Name
             leetodo(Tabla_Baterias[indice],true,false,false);
             return Tabla_Baterias[indice].nombre;
         }break;
         case 2:{                //funcion 1 Battery type
             leetodo(Tabla_Baterias[indice],true,false,false);
             return Tabla_Baterias[indice].tipo;
         }break;
         case 3:{                //funcion 1 Battery technology
             leetodo(Tabla_Baterias[indice],true,false,false);
             return Tabla_Baterias[indice].tecnologia;
         }break;
         case 4:{                //funcion 1 Battery charge
             ostringstream converter;
             leetodo(Tabla_Baterias[indice],false,true,false);
             converter << Tabla_Baterias[indice].carga;
             return converter.str();
         }break;
         case 5:{                //funcion 1 Battery state
             leetodo(Tabla_Baterias[indice],false,false,true);
             return Tabla_Baterias[indice].estado;
         }break;
     }
}

void Destruct(){
     //TODO
     loaded = false;
}




More information about the dbus mailing list