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