This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository evisum.

View the commit online.

commit e084b9397d80d2477fd21196de3bede22cbe2fae
Author: Alastair Poole <[email protected]>
AuthorDate: Sat Mar 28 12:32:53 2026 +0000

    background: use our background thread.
    
    Need some locking here and remove popen call it's terrible.
    
    Read the code netty.
---
 src/bin/background/evisum_background.c | 104 +++++++++++
 src/bin/background/evisum_background.h |   5 +
 src/bin/system/machine.h               |  11 ++
 src/bin/system/machine/network.x       | 318 +++++++++++++++++++++++++++++++++
 src/bin/ui/evisum_ui.c                 |   4 +-
 src/bin/ui/evisum_ui.h                 |   6 +
 src/bin/ui/evisum_ui_process_list.c    |  23 ++-
 src/bin/ui/evisum_ui_process_view.c    |  21 ++-
 src/bin/ui/evisum_ui_process_view.h    |   2 +-
 9 files changed, 476 insertions(+), 18 deletions(-)

diff --git a/src/bin/background/evisum_background.c b/src/bin/background/evisum_background.c
index 68c38b3..9f50a25 100644
--- a/src/bin/background/evisum_background.c
+++ b/src/bin/background/evisum_background.c
@@ -1,12 +1,79 @@
 #include "evisum_background.h"
 #include "../system/filesystems.h"
+#include "../system/machine.h"
 
 #include <Eina.h>
+#include <stdint.h>
+
+typedef struct {
+    uint64_t in;
+    uint64_t out;
+} Proc_Net_Stats;
+
+static Proc_Net_Stats *
+_proc_net_stats_get_or_add(Eina_Hash *hash, int64_t pid) {
+    Proc_Net_Stats *stats = eina_hash_find(hash, &pid);
+    if (stats) return stats;
+
+    stats = calloc(1, sizeof(*stats));
+    if (!stats) return NULL;
+
+    eina_hash_add(hash, &pid, stats);
+    return stats;
+}
+
+static Eina_Hash *
+_proc_net_stats_collect(void) {
+    Eina_Hash *hash = NULL;
+    proc_net_t **procs = NULL;
+    int n = 0;
+
+    hash = eina_hash_int64_new(free);
+    if (!hash) return NULL;
+
+    procs = system_network_process_usage_get(&n);
+    for (int i = 0; i < n; i++) {
+        int64_t pid;
+        Proc_Net_Stats *stats;
+
+        if (!procs[i]) continue;
+        if ((!procs[i]->in) && (!procs[i]->out)) continue;
+
+        pid = procs[i]->pid;
+        stats = _proc_net_stats_get_or_add(hash, pid);
+        if (!stats) continue;
+
+        stats->in = procs[i]->in;
+        stats->out = procs[i]->out;
+    }
+
+    system_network_process_usage_free(procs, n);
+    return hash;
+}
+
+static void
+_proc_net_stats_refresh(Evisum_Ui *ui) {
+    Eina_Hash *next;
+
+    next = _proc_net_stats_collect();
+    if (!next) return;
+
+    eina_lock_take(&ui->background.proc_net_lock);
+    if (ui->background.proc_net_stats) eina_hash_free(ui->background.proc_net_stats);
+    ui->background.proc_net_stats = next;
+    eina_lock_release(&ui->background.proc_net_lock);
+}
 
 void
 evisum_background_init(Evisum_Ui *ui) {
     meminfo_t memory;
 
+    if (!ui->background.proc_net_lock_init) {
+        eina_lock_new(&ui->background.proc_net_lock);
+        ui->background.proc_net_lock_init = EINA_TRUE;
+    }
+    _proc_net_stats_refresh(ui);
+
     system_memory_usage_get(&memory);
     ui->mem_total = memory.total;
     ui->mem_used = memory.used;
@@ -33,6 +100,43 @@ evisum_background_poller(void *data, Ecore_Thread *thread) {
         ui->mem_used = memory.used;
         if (file_system_in_use("ZFS")) ui->mem_used += memory.zfs_arc_used;
 
+        _proc_net_stats_refresh(ui);
         ui->cpu_usage = percent / system_cpu_online_count_get();
     }
 }
+
+void
+evisum_background_proc_net_get(Evisum_Ui *ui, pid_t pid, uint64_t *net_in, uint64_t *net_out) {
+    int64_t key;
+    Proc_Net_Stats *stats;
+
+    if (net_in) *net_in = 0;
+    if (net_out) *net_out = 0;
+    if (!ui) return;
+    if (pid <= 0) return;
+    if (!ui->background.proc_net_lock_init) return;
+
+    key = pid;
+    eina_lock_take(&ui->background.proc_net_lock);
+    stats = ui->background.proc_net_stats ? eina_hash_find(ui->background.proc_net_stats, &key) : NULL;
+    if (stats) {
+        if (net_in) *net_in = stats->in;
+        if (net_out) *net_out = stats->out;
+    }
+    eina_lock_release(&ui->background.proc_net_lock);
+}
+
+void
+evisum_background_shutdown(Evisum_Ui *ui) {
+    if (!ui) return;
+    if (!ui->background.proc_net_lock_init) return;
+
+    eina_lock_take(&ui->background.proc_net_lock);
+    if (ui->background.proc_net_stats) {
+        eina_hash_free(ui->background.proc_net_stats);
+        ui->background.proc_net_stats = NULL;
+    }
+    eina_lock_release(&ui->background.proc_net_lock);
+    eina_lock_free(&ui->background.proc_net_lock);
+    ui->background.proc_net_lock_init = EINA_FALSE;
+}
diff --git a/src/bin/background/evisum_background.h b/src/bin/background/evisum_background.h
index 5ecab3c..7300b04 100644
--- a/src/bin/background/evisum_background.h
+++ b/src/bin/background/evisum_background.h
@@ -3,9 +3,14 @@
 
 #include "../ui/evisum_ui.h"
 #include <Ecore.h>
+#include <sys/types.h>
 
 void evisum_background_poller(void *data, Ecore_Thread *thread);
 
 void evisum_background_init(Evisum_Ui *ui);
 
+void evisum_background_shutdown(Evisum_Ui *ui);
+
+void evisum_background_proc_net_get(Evisum_Ui *ui, pid_t pid, uint64_t *net_in, uint64_t *net_out);
+
 #endif
diff --git a/src/bin/system/machine.h b/src/bin/system/machine.h
index 96780d9..1e2db3f 100644
--- a/src/bin/system/machine.h
+++ b/src/bin/system/machine.h
@@ -9,6 +9,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <sys/types.h>
 
 typedef struct {
     unsigned long total;
@@ -82,6 +83,12 @@ typedef struct {
     } xfer;
 } net_iface_t;
 
+typedef struct {
+    pid_t pid;
+    uint64_t in;
+    uint64_t out;
+} proc_net_t;
+
 int system_cpu_online_count_get(void);
 
 int system_cpu_count_get(void);
@@ -120,4 +127,8 @@ void system_power_state_free(power_t *power);
 
 net_iface_t **system_network_ifaces_get(int *n);
 
+proc_net_t **system_network_process_usage_get(int *n);
+
+void system_network_process_usage_free(proc_net_t **procs, int n);
+
 #endif
diff --git a/src/bin/system/machine/network.x b/src/bin/system/machine/network.x
index 34a988f..efca65b 100644
--- a/src/bin/system/machine/network.x
+++ b/src/bin/system/machine/network.x
@@ -14,6 +14,15 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#if defined(__linux__)
+#include <stddef.h>
+#include <netinet/in.h>
+#include <linux/inet_diag.h>
+#include <linux/sock_diag.h>
+#include <linux/tcp.h>
+#include <linux/rtnetlink.h>
+#endif
+
 #if defined(__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__)
 static net_iface_t **
 _freebsd_generic_network_status(int *n)
@@ -174,6 +183,293 @@ _linux_generic_network_status(int *n)
    return ifaces;
 }
 
+typedef struct {
+   unsigned long inode;
+   uint64_t in;
+   uint64_t out;
+} Linux_Proc_Socket_Stat;
+
+static int
+_linux_proc_socket_stat_cmp(const void *a, const void *b)
+{
+   const Linux_Proc_Socket_Stat *sa = a;
+   const Linux_Proc_Socket_Stat *sb = b;
+
+   if (sa->inode < sb->inode) return -1;
+   if (sa->inode > sb->inode) return 1;
+   return 0;
+}
+
+static bool
+_linux_proc_socket_stat_add(Linux_Proc_Socket_Stat **stats, int *count, int *capacity, unsigned long inode, uint64_t in, uint64_t out)
+{
+   Linux_Proc_Socket_Stat *tmp;
+   int next_capacity;
+
+   if (*count >= *capacity)
+     {
+        next_capacity = *capacity ? *capacity * 2 : 256;
+        tmp = realloc(*stats, next_capacity * sizeof(**stats));
+        if (!tmp) return false;
+        *stats = tmp;
+        *capacity = next_capacity;
+     }
+
+   (*stats)[*count].inode = inode;
+   (*stats)[*count].in = in;
+   (*stats)[*count].out = out;
+   (*count)++;
+
+   return true;
+}
+
+static void
+_linux_proc_socket_diag_collect(int family, Linux_Proc_Socket_Stat **stats, int *count, int *capacity)
+{
+   int fd;
+   ssize_t sent;
+   struct
+   {
+      struct nlmsghdr nlh;
+      struct inet_diag_req_v2 req;
+   } request;
+   char buffer[8192];
+
+   fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
+   if (fd < 0) return;
+
+   memset(&request, 0, sizeof(request));
+   request.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(request.req));
+   request.nlh.nlmsg_type = SOCK_DIAG_BY_FAMILY;
+   request.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+   request.req.sdiag_family = family;
+   request.req.sdiag_protocol = IPPROTO_TCP;
+   request.req.idiag_states = -1;
+   request.req.idiag_ext = (1 << (INET_DIAG_INFO - 1));
+
+   sent = send(fd, &request, request.nlh.nlmsg_len, 0);
+   if (sent < 0)
+     {
+        close(fd);
+        return;
+     }
+
+   while (1)
+     {
+        ssize_t len = recv(fd, buffer, sizeof(buffer), 0);
+        struct nlmsghdr *nlh;
+
+        if (len <= 0) break;
+
+        for (nlh = (struct nlmsghdr *) buffer; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len))
+          {
+             struct inet_diag_msg *diag;
+             struct rtattr *attr;
+             int attr_len;
+
+             if (nlh->nlmsg_type == NLMSG_DONE)
+               {
+                  close(fd);
+                  return;
+               }
+             if (nlh->nlmsg_type == NLMSG_ERROR)
+               {
+                  close(fd);
+                  return;
+               }
+             if (nlh->nlmsg_type != SOCK_DIAG_BY_FAMILY) continue;
+             if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*diag))) continue;
+
+             diag = NLMSG_DATA(nlh);
+             attr_len = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*diag));
+             if (attr_len <= 0) continue;
+
+             for (attr = (struct rtattr *) (diag + 1); RTA_OK(attr, attr_len); attr = RTA_NEXT(attr, attr_len))
+               {
+                  struct tcp_info *tcpi;
+                  size_t tcpi_len;
+                  uint64_t in = 0, out = 0;
+
+                  if (attr->rta_type != INET_DIAG_INFO) continue;
+
+                  tcpi = RTA_DATA(attr);
+                  tcpi_len = RTA_PAYLOAD(attr);
+
+                  if (tcpi_len >= (offsetof(struct tcp_info, tcpi_bytes_received) + sizeof(tcpi->tcpi_bytes_received)))
+                    in = tcpi->tcpi_bytes_received;
+                  if (tcpi_len >= (offsetof(struct tcp_info, tcpi_bytes_acked) + sizeof(tcpi->tcpi_bytes_acked)))
+                    out = tcpi->tcpi_bytes_acked;
+
+                  if ((!in) && (!out)) continue;
+                  if (!_linux_proc_socket_stat_add(stats, count, capacity, diag->idiag_inode, in, out))
+                    {
+                       close(fd);
+                       return;
+                    }
+               }
+          }
+     }
+
+   close(fd);
+}
+
+static Linux_Proc_Socket_Stat *
+_linux_proc_socket_stats_get(int *count)
+{
+   Linux_Proc_Socket_Stat *stats;
+   int capacity = 0, out_count = 0;
+
+   *count = 0;
+
+   stats = NULL;
+   _linux_proc_socket_diag_collect(AF_INET, &stats, &out_count, &capacity);
+   _linux_proc_socket_diag_collect(AF_INET6, &stats, &out_count, &capacity);
+
+   if (!out_count) return stats;
+
+   qsort(stats, out_count, sizeof(*stats), _linux_proc_socket_stat_cmp);
+
+   int write = 0;
+   for (int read = 0; read < out_count; read++)
+     {
+        if ((write > 0) && (stats[read].inode == stats[write - 1].inode))
+          {
+             stats[write - 1].in += stats[read].in;
+             stats[write - 1].out += stats[read].out;
+             continue;
+          }
+        if (write != read) stats[write] = stats[read];
+        write++;
+     }
+
+   *count = write;
+   return stats;
+}
+
+static const Linux_Proc_Socket_Stat *
+_linux_proc_socket_stat_find(const Linux_Proc_Socket_Stat *stats, int count, unsigned long inode)
+{
+   Linux_Proc_Socket_Stat key;
+   key.inode = inode;
+   key.in = 0;
+   key.out = 0;
+   return bsearch(&key, stats, count, sizeof(*stats), _linux_proc_socket_stat_cmp);
+}
+
+static bool
+_linux_proc_net_usage_add(proc_net_t ***procs, int *n, pid_t pid, uint64_t in, uint64_t out)
+{
+   proc_net_t **tmp;
+   proc_net_t *proc;
+
+   tmp = realloc(*procs, (*n + 1) * sizeof(**procs));
+   if (!tmp) return false;
+   *procs = tmp;
+
+   proc = calloc(1, sizeof(*proc));
+   if (!proc) return false;
+
+   proc->pid = pid;
+   proc->in = in;
+   proc->out = out;
+
+   (*procs)[*n] = proc;
+   (*n)++;
+
+   return true;
+}
+
+static proc_net_t **
+_linux_process_network_usage_get(int *n)
+{
+   DIR *dir;
+   struct dirent *entry;
+   Linux_Proc_Socket_Stat *sockets;
+   int socket_count;
+   proc_net_t **procs = NULL;
+
+   *n = 0;
+
+   sockets = _linux_proc_socket_stats_get(&socket_count);
+   if ((!sockets) || (!socket_count))
+     {
+        free(sockets);
+        return NULL;
+     }
+
+   dir = opendir("/proc");
+   if (!dir)
+     {
+        free(sockets);
+        return NULL;
+     }
+
+   while ((entry = readdir(dir)))
+     {
+        char *end = NULL;
+        unsigned long pid_ul;
+        pid_t pid;
+        char fd_dir[PATH_MAX];
+        DIR *fd;
+        struct dirent *fd_entry;
+        uint64_t in = 0, out = 0;
+
+        if (!isdigit((unsigned char) entry->d_name[0])) continue;
+
+        pid_ul = strtoul(entry->d_name, &end, 10);
+        if (!end || *end) continue;
+        if (pid_ul > INT_MAX) continue;
+        pid = (pid_t) pid_ul;
+
+        snprintf(fd_dir, sizeof(fd_dir), "/proc/%d/fd", pid);
+        fd = opendir(fd_dir);
+        if (!fd) continue;
+
+        while ((fd_entry = readdir(fd)))
+          {
+             char link_path[PATH_MAX];
+             char target[256];
+             ssize_t len;
+             unsigned long inode;
+             const Linux_Proc_Socket_Stat *sock;
+
+             if (fd_entry->d_name[0] == '.') continue;
+
+             size_t base_len = strlen(fd_dir);
+             size_t name_len = strlen(fd_entry->d_name);
+             if ((base_len + 1 + name_len + 1) > sizeof(link_path)) continue;
+             memcpy(link_path, fd_dir, base_len);
+             link_path[base_len] = '/';
+             memcpy(link_path + base_len + 1, fd_entry->d_name, name_len);
+             link_path[base_len + 1 + name_len] = '\0';
+             len = readlink(link_path, target, sizeof(target) - 1);
+             if (len <= 0) continue;
+
+             target[len] = '\0';
+             if (strncmp(target, "socket:[", 8)) continue;
+
+             inode = strtoul(target + 8, &end, 10);
+             if (!end || (*end != ']')) continue;
+
+             sock = _linux_proc_socket_stat_find(sockets, socket_count, inode);
+             if (!sock) continue;
+
+             in += sock->in;
+             out += sock->out;
+          }
+
+        closedir(fd);
+
+        if ((!in) && (!out)) continue;
+        if (!_linux_proc_net_usage_add(&procs, n, pid, in, out)) break;
+     }
+
+   closedir(dir);
+   free(sockets);
+
+   return procs;
+}
+
 #endif
 
 net_iface_t **
@@ -190,3 +486,25 @@ system_network_ifaces_get(int *n)
    return NULL;
 #endif
 }
+
+proc_net_t **
+system_network_process_usage_get(int *n)
+{
+   *n = 0;
+#if defined(__linux__)
+   return _linux_process_network_usage_get(n);
+#else
+   return NULL;
+#endif
+}
+
+void
+system_network_process_usage_free(proc_net_t **procs, int n)
+{
+   if (!procs) return;
+
+   for (int i = 0; i < n; i++)
+     free(procs[i]);
+
+   free(procs);
+}
diff --git a/src/bin/ui/evisum_ui.c b/src/bin/ui/evisum_ui.c
index e3f50fa..748908c 100644
--- a/src/bin/ui/evisum_ui.c
+++ b/src/bin/ui/evisum_ui.c
@@ -4,6 +4,7 @@
 #include "evisum_server.h"
 
 #include "system/filesystems.h"
+#include "background/evisum_background.h"
 
 #include "evisum_ui.h"
 #include "ui/evisum_ui_colors.h"
@@ -678,7 +679,7 @@ evisum_ui_activate(Evisum_Ui *ui, Evisum_Action action, int pid) {
             evisum_ui_process_list_win_add(ui);
             break;
         case EVISUM_ACTION_PROCESS:
-            evisum_ui_process_view_win_add(pid, PROC_VIEW_DEFAULT);
+            evisum_ui_process_view_win_add(ui, pid, PROC_VIEW_DEFAULT);
             break;
         case EVISUM_ACTION_CPU:
             evisum_ui_cpu_win_add(ui);
@@ -704,6 +705,7 @@ evisum_ui_shutdown(Evisum_Ui *ui) {
 
     ecore_thread_cancel(ui->background_poll_thread);
     ecore_thread_wait(ui->background_poll_thread, 0.5);
+    evisum_background_shutdown(ui);
 
     if (ui->cpu.visual) free(ui->cpu.visual);
     free(ui);
diff --git a/src/bin/ui/evisum_ui.h b/src/bin/ui/evisum_ui.h
index 418827b..5ee6f87 100644
--- a/src/bin/ui/evisum_ui.h
+++ b/src/bin/ui/evisum_ui.h
@@ -96,6 +96,12 @@ typedef struct _Evisum_Ui {
         int x, y;
         Eina_Bool restart;
     } network;
+
+    struct {
+        Eina_Hash *proc_net_stats;
+        Eina_Lock proc_net_lock;
+        Eina_Bool proc_net_lock_init;
+    } background;
 } Evisum_Ui;
 
 typedef struct _Battery {
diff --git a/src/bin/ui/evisum_ui_process_list.c b/src/bin/ui/evisum_ui_process_list.c
index 117f44f..c97044c 100644
--- a/src/bin/ui/evisum_ui_process_list.c
+++ b/src/bin/ui/evisum_ui_process_list.c
@@ -5,6 +5,7 @@
 #include "evisum_ui_widget_exel.h"
 #include "ui/evisum_ui_process_list.h"
 #include "ui/evisum_ui_process_view.h"
+#include "../background/evisum_background.h"
 
 #include <stdio.h>
 #define __STDC_FORMAT_MACROS
@@ -639,10 +640,11 @@ _evisum_ui_process_list_search_trim(Eina_List *list, Evisum_Ui_Process_List_View
             int64_t id = proc->pid;
 
             if ((cache = eina_hash_find(view->proc_usage_cache, &id))) {
-                uint64_t net_in_abs = proc->net_in;
-                uint64_t net_out_abs = proc->net_out;
+                uint64_t net_in_abs = 0;
+                uint64_t net_out_abs = 0;
                 int elapsed = view->ui->proc.poll_delay;
                 if (elapsed <= 0) elapsed = 1;
+                evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
 
                 if (cache->start != proc->start) {
                     cache->start = proc->start;
@@ -671,10 +673,13 @@ _evisum_ui_process_list_search_trim(Eina_List *list, Evisum_Ui_Process_List_View
             } else {
                 cache = calloc(1, sizeof(Proc_Usage_Cache));
                 if (cache) {
+                    uint64_t net_in_abs = 0;
+                    uint64_t net_out_abs = 0;
+                    evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
                     cache->start = proc->start;
                     cache->cpu_time = proc->cpu_time;
-                    cache->net_in = proc->net_in;
-                    cache->net_out = proc->net_out;
+                    cache->net_in = net_in_abs;
+                    cache->net_out = net_out_abs;
                     proc->net_in = 0;
                     proc->net_out = 0;
                     eina_hash_add(view->proc_usage_cache, &id, cache);
@@ -945,7 +950,7 @@ _evisum_ui_process_list_item_menu_manual_cb(void *data, Evas_Object *obj EINA_UN
 
     _evisum_ui_process_list_item_menu_cancel_cb(view, NULL, NULL);
 
-    evisum_ui_process_view_win_add(view->selected_pid, PROC_VIEW_MANUAL);
+    evisum_ui_process_view_win_add(view->ui, view->selected_pid, PROC_VIEW_MANUAL);
 }
 
 static void
@@ -954,7 +959,7 @@ _evisum_ui_process_list_item_menu_threads_cb(void *data, Evas_Object *obj EINA_U
 
     _evisum_ui_process_list_item_menu_cancel_cb(view, NULL, NULL);
 
-    evisum_ui_process_view_win_add(view->selected_pid, PROC_VIEW_THREADS);
+    evisum_ui_process_view_win_add(view->ui, view->selected_pid, PROC_VIEW_THREADS);
 }
 
 static void
@@ -963,7 +968,7 @@ _evisum_ui_process_list_item_menu_children_cb(void *data, Evas_Object *obj EINA_
 
     _evisum_ui_process_list_item_menu_cancel_cb(view, NULL, NULL);
 
-    evisum_ui_process_view_win_add(view->selected_pid, PROC_VIEW_CHILDREN);
+    evisum_ui_process_view_win_add(view->ui, view->selected_pid, PROC_VIEW_CHILDREN);
 }
 
 static void
@@ -972,7 +977,7 @@ _evisum_ui_process_list_item_menu_general_cb(void *data, Evas_Object *obj EINA_U
 
     _evisum_ui_process_list_item_menu_cancel_cb(view, NULL, NULL);
 
-    evisum_ui_process_view_win_add(view->selected_pid, PROC_VIEW_DEFAULT);
+    evisum_ui_process_view_win_add(view->ui, view->selected_pid, PROC_VIEW_DEFAULT);
 }
 
 static void
@@ -1078,7 +1083,7 @@ _evisum_ui_process_list_item_pid_clicked_cb(void *data, Evas_Object *obj EINA_UN
     if (!proc) return;
 
     view->selected_pid = proc->pid;
-    evisum_ui_process_view_win_add(proc->pid, PROC_VIEW_DEFAULT);
+    evisum_ui_process_view_win_add(view->ui, proc->pid, PROC_VIEW_DEFAULT);
 }
 
 static void
diff --git a/src/bin/ui/evisum_ui_process_view.c b/src/bin/ui/evisum_ui_process_view.c
index 67b2d5f..14eb6fe 100644
--- a/src/bin/ui/evisum_ui_process_view.c
+++ b/src/bin/ui/evisum_ui_process_view.c
@@ -2,11 +2,13 @@
 #include "evisum_ui_colors.h"
 #include "evisum_ui_widget_exel.h"
 #include "../system/process.h"
+#include "../background/evisum_background.h"
 #include "util.c"
 #define __STDC_FORMAT_MACROS
 #include <inttypes.h>
 
 typedef struct {
+    Evisum_Ui *ui;
     Evas_Object *win;
     Evas_Object *tb_content;
 
@@ -343,25 +345,29 @@ _evisum_ui_process_view_threads_cpu_usage(Evisum_Ui_Process_View *view, Proc_Inf
 
 static void
 _evisum_ui_process_view_btn_ppid_clicked_cb(void *data, Evas_Object *obj, void *event_info) {
+    Evisum_Ui_Process_View *view;
     Evas_Object *entry;
     const char *txt;
     Proc_Info *proc;
 
-    entry = data;
+    view = data;
+    entry = view->general.entry_ppid;
     txt = elm_object_text_get(entry);
     proc = proc_info_by_pid(atoll(txt));
 
     if (!proc) return;
 
-    evisum_ui_process_view_win_add(proc->pid, PROC_VIEW_DEFAULT);
+    evisum_ui_process_view_win_add(view->ui, proc->pid, PROC_VIEW_DEFAULT);
     proc_info_free(proc);
 }
 
 static void
 _evisum_ui_process_view_item_children_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) {
+    Evisum_Ui_Process_View *view;
     Elm_Object_Item *it;
     Proc_Info *proc;
 
+    view = data;
     it = event_info;
 
     evisum_ui_widget_exel_genlist_item_selected_set(it, 0);
@@ -369,7 +375,7 @@ _evisum_ui_process_view_item_children_clicked_cb(void *data, Evas_Object *obj EI
     proc = evisum_ui_widget_exel_object_item_data_get(it);
     if (!proc) return;
 
-    evisum_ui_process_view_win_add(proc->pid, PROC_VIEW_DEFAULT);
+    evisum_ui_process_view_win_add(view->ui, proc->pid, PROC_VIEW_DEFAULT);
 }
 
 static char *
@@ -831,8 +837,7 @@ _evisum_ui_process_view_proc_info_feedback_cb(void *data, Ecore_Thread *thread,
 
     proc->cpu_usage = cpu_usage;
 #if defined(__linux__)
-    net_in_abs = proc->net_in;
-    net_out_abs = proc->net_out;
+    evisum_background_proc_net_get(view->ui, proc->pid, &net_in_abs, &net_out_abs);
 
     if ((view->pid_net_in) && (net_in_abs >= view->pid_net_in))
         net_in = (net_in_abs - view->pid_net_in) / elapsed;
@@ -982,7 +987,7 @@ _evisum_ui_process_view_general_tab_add(Evas_Object *parent, Evisum_Ui_Process_V
     evas_object_show(btn);
 
     view->general.entry_ppid = entry = _evisum_ui_process_view_entry_add(parent);
-    evas_object_smart_callback_add(btn, "clicked", _evisum_ui_process_view_btn_ppid_clicked_cb, entry);
+    evas_object_smart_callback_add(btn, "clicked", _evisum_ui_process_view_btn_ppid_clicked_cb, view);
     elm_table_pack(tb, entry, 1, i++, 1, 1);
 
 #if defined(__MacOS__)
@@ -1497,11 +1502,13 @@ _evisum_ui_process_view_activate(Evisum_Ui_Process_View *view, Evisum_Proc_Actio
 }
 
 void
-evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action) {
+evisum_ui_process_view_win_add(Evisum_Ui *ui, int pid, Evisum_Proc_Action action) {
     Evas_Object *win, *ic, *bx, *tabs, *tb;
     Proc_Info *proc;
 
     Evisum_Ui_Process_View *view = calloc(1, sizeof(Evisum_Ui_Process_View));
+    if (!view) return;
+    view->ui = ui;
     view->selected_pid = pid;
     view->poll_delay = 1;
     view->threads.widget_exel = NULL;
diff --git a/src/bin/ui/evisum_ui_process_view.h b/src/bin/ui/evisum_ui_process_view.h
index 7daae18..305a8b4 100644
--- a/src/bin/ui/evisum_ui_process_view.h
+++ b/src/bin/ui/evisum_ui_process_view.h
@@ -10,6 +10,6 @@ typedef enum {
     PROC_VIEW_MANUAL = 3,
 } Evisum_Proc_Action;
 
-void evisum_ui_process_view_win_add(int pid, Evisum_Proc_Action action);
+void evisum_ui_process_view_win_add(Evisum_Ui *ui, int pid, Evisum_Proc_Action action);
 
 #endif

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to