Hi,
batgets cpu usage goes up to 100% after resuming. 

During resume the sysfs entry for the battery briefly disappears, same
when I take it out. I don't know if that is normal behavior
or if my laptop is just weird..

It gets stuck in this loop while attempting to read from it:

line 454:

for (;;)
  {
     char buf[1024];
     int num;
             
     if ((num = read(sysev->fd, buf, sizeof(buf))) < 1)
       {
          lost = ((errno == EIO) ||
                  (errno == EBADF) ||
                  (errno == EPIPE) ||
                  (errno == EINVAL) ||
                  (errno == ENOSPC));
          if (num == 0) break;
       }
  }

Errno is set to ENODEV and read() returns -1 on error so it never leaves
that loop.

e_battery_stuckage.diff causes batget to stop monitoring the battery
if the file disappears.

e_battery_dbus_sysfs.diff allows batget to monitor battery presence via
dbus/hal. I've never done anything with dbus or efl, and my C knowledge
is a bit shaky so this may not be completely correct. It seems to work
fine here though.

stefan
--- src_old/modules/battery/batget.c	2008-04-12 02:45:18.000000000 +0200
+++ src/modules/battery/batget.c	2008-04-12 02:45:28.000000000 +0200
@@ -462,8 +462,9 @@
 			  (errno == EBADF) ||
 			  (errno == EPIPE) ||
 			  (errno == EINVAL) ||
-			  (errno == ENOSPC));
-		  if (num == 0) break;
+			  (errno == ENOSPC) ||
+			  (errno == ENODEV));
+		  if (num <= 0) break;
 	       }
 	  }
 	if (lost)
--- src_old/modules/battery/batget.c	2008-04-12 02:48:46.000000000 +0200
+++ src/modules/battery/batget.c	2008-04-12 02:49:04.000000000 +0200
@@ -410,10 +410,15 @@
 static void linux_sys_class_power_supply_check(void);
 typedef struct _Sys_Class_Power_Supply_Uevent Sys_Class_Power_Supply_Uevent;
 
+static void linux_sys_class_power_supply_sysev_init(Sys_Class_Power_Supply_Uevent *sysev);
+static int linux_sys_class_powe_supply_cb_delay_check(void *data);
+
 #define BASIS_CHARGE  1
 #define BASIS_ENERGY  2
 #define BASIS_VOLTAGE 3
 
+#define UDI_BAT_HEAD "/org/freedesktop/Hal/devices/computer_power_supply_battery_"
+
 struct _Sys_Class_Power_Supply_Uevent
 {
    char *name;
@@ -433,6 +438,89 @@
 static Ecore_List *events = NULL;
 static Ecore_Timer *sys_class_delay_check = NULL;
 
+
+static void
+linux_sys_class_power_supply_battery_add(char * name)
+{
+   char buf[4096];
+   Sys_Class_Power_Supply_Uevent *sysev;
+
+   sysev = E_NEW(Sys_Class_Power_Supply_Uevent, 1);
+   sysev->name = strdup(name);
+   snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/uevent", name);
+   sysev->fd = open(buf, O_RDONLY);
+   if (sysev->fd >= 0)
+     sysev->fd_handler = ecore_main_fd_handler_add(sysev->fd,
+						   ECORE_FD_READ,
+						   linux_sys_class_power_supply_cb_event_fd_active,
+						   sysev,
+						   NULL, NULL);
+   ecore_list_append(events, sysev);
+   linux_sys_class_power_supply_sysev_init(sysev);
+}
+
+static void
+linux_sys_class_power_supply_battery_remove(char * name)
+{
+  Sys_Class_Power_Supply_Uevent *sysev;
+
+  ecore_list_first_goto(events);
+  while ((sysev = ecore_list_next(events)))
+    {
+      if (!strcasecmp(name, sysev->name)) 
+      {
+	ecore_list_remove(events);
+	if (sysev->fd_handler)
+	  ecore_main_fd_handler_del(sysev->fd_handler);
+	if (sysev->fd >= 0) close(sysev->fd);
+	free(sysev->name);
+	free(sysev);
+
+	return;
+      }
+    }
+}
+
+#ifdef HAVE_EDBUS
+
+static void
+linux_sys_class_power_supply_dbus_cb(void * data, DBusMessage *msg)
+{
+   DBusError err;
+   char* udi;
+   int offset = strlen(UDI_BAT_HEAD);
+   
+   dbus_error_init(&err);
+   dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID);
+   if (dbus_error_is_set(&err))
+     {
+	dbus_error_free(&err);
+	return;
+     }
+
+   if (!strncmp(udi, UDI_BAT_HEAD, offset))
+     {
+	if (strlen(udi) > offset && strlen(udi) < offset + 4096)
+	  {
+	     char name[4096];
+	     const char *member = dbus_message_get_member(msg);
+ 
+	     strcpy(name, udi+offset);
+
+	     if (!strcmp(member, "DeviceAdded"))
+	       {
+		  linux_sys_class_power_supply_battery_add(name);
+	       }
+	     else
+	       {
+		  linux_sys_class_power_supply_battery_remove(name);
+	       }
+	  }
+     }   
+}
+
+#endif
+
 static int
 linux_sys_class_powe_supply_cb_delay_check(void *data)
 {
@@ -588,7 +676,6 @@
      {
 	Ecore_List *bats;
 	char *name;
-	char buf[4096];
 	
 	bats = ecore_file_ls("/sys/class/power_supply/");
 	if (bats)
@@ -596,21 +683,8 @@
 	     events = ecore_list_new();
 	     while ((name = ecore_list_next(bats)))
 	       {
-		  Sys_Class_Power_Supply_Uevent *sysev;
-	     
 		  if (strncasecmp("bat", name, 3)) continue;
-		  sysev = E_NEW(Sys_Class_Power_Supply_Uevent, 1);
-		  sysev->name = strdup(name);
-		  snprintf(buf, sizeof(buf), "/sys/class/power_supply/%s/uevent", name);
-		  sysev->fd = open(buf, O_RDONLY);
-		  if (sysev->fd >= 0)
-		    sysev->fd_handler = ecore_main_fd_handler_add(sysev->fd,
-								  ECORE_FD_READ,
-								  linux_sys_class_power_supply_cb_event_fd_active,
-								  sysev,
-								  NULL, NULL);
-		  ecore_list_append(events, sysev);
-		  linux_sys_class_power_supply_sysev_init(sysev);
+		  linux_sys_class_power_supply_battery_add(name);
 	       }
 	     ecore_list_destroy(bats);
 	  }
@@ -1312,10 +1386,37 @@
 
 
 
+#ifdef HAVE_EDBUS
 
+static E_DBus_Connection *dbus_conn;
 
+static void
+battery_dbus_init(E_DBus_Signal_Cb signal_cb)
+{  
+   e_dbus_init();
+
+   dbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM);
+   e_dbus_signal_handler_add(dbus_conn,
+			     "org.freedesktop.Hal", 
+			     "/org/freedesktop/Hal/Manager", 
+			     "org.freedesktop.Hal.Manager",
+			     "DeviceAdded",
+			     signal_cb, NULL);
+   e_dbus_signal_handler_add(dbus_conn, 
+			     "org.freedesktop.Hal", 
+			     "/org/freedesktop/Hal/Manager", 
+			     "org.freedesktop.Hal.Manager",
+			     "DeviceRemoved", 
+			     signal_cb, NULL);
+}
 
+static void
+battery_dbus_shutdown()
+{
+   e_dbus_connection_close(dbus_conn);
+}
 
+#endif
 
 
 static void
@@ -1352,6 +1453,9 @@
      {
 	mode = CHECK_SYS_CLASS_POWER_SUPPLY;
 	linux_sys_class_power_supply_init();
+#ifdef HAVE_EDBUS
+	battery_dbus_init(linux_sys_class_power_supply_dbus_cb);
+#endif
      }
    else if (ecore_file_is_dir("/proc/acpi")) /* <= 2.6.24 */
      {
@@ -1388,7 +1492,7 @@
    switch (mode)
      {
       case CHECK_ACPI:
-       bsd_acpi_check();
+	bsd_acpi_check();
 	break;
       case CHECK_APM:
 	bsd_apm_check();
@@ -1461,7 +1565,11 @@
    poll_cb(NULL);
    
    ecore_main_loop_begin();
-   
+
+#if HAVE_EDBUS
+   battery_dbus_shutdown();
+#endif
+
    ecore_con_shutdown();
    ecore_file_shutdown();
    ecore_shutdown();
--- src_old/modules/battery/Makefile.am	2008-04-12 02:48:46.000000000 +0200
+++ src/modules/battery/Makefile.am	2008-04-12 02:49:04.000000000 +0200
@@ -36,7 +36,7 @@
 
 noinst_PROGRAMS        = batget
 batget_SOURCES         = batget.c
-batget_LDFLAGS         = @BATTERY_LIBS@
+batget_LDFLAGS         = @BATTERY_LIBS@ @E_DBUS_LIBS@
 
 
 uninstall:
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to