summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-07-17 16:47:23 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-07-17 16:47:23 +0100
commit2a69b89487a6ec7cc8ce9e43948a5c3357974a42 (patch)
tree97770ab3d4b76f655acc46c312cc38d8c68cc184
parentbc46ac8aaf8378b6399f1e81ec19516cabf020d1 (diff)
Enable rudimentary TCP connectionsHEADmaster
-rw-r--r--src/app.c71
-rw-r--r--src/lwp.c54
-rw-r--r--src/procmap-store.c10
-rw-r--r--src/procmap.c6
4 files changed, 126 insertions, 15 deletions
diff --git a/src/app.c b/src/app.c
index cff3f7e..d30a019 100644
--- a/src/app.c
+++ b/src/app.c
@@ -73,7 +73,8 @@ struct _app {
Client client;
- GUnixSocket *lwp_events;
+ GUnixSocket *lwp_unix;
+ GTcpSocket *lwp_tcp;
GTcpSocket *vg_events;
GTcpSocket *vg_log;
};
@@ -1954,9 +1955,9 @@ _update_client (App *app)
}
static gboolean
-lwp_events_server_cb (GIOChannel *source,
- GIOCondition condition,
- gpointer data)
+lwp_unix_server_cb (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
{
App *app = data;
@@ -1964,7 +1965,7 @@ lwp_events_server_cb (GIOChannel *source,
GUnixSocket *client;
gboolean update = FALSE;
- client = gnet_unix_socket_server_accept (app->lwp_events);
+ client = gnet_unix_socket_server_accept (app->lwp_unix);
do {
GIOChannel *io = gnet_unix_socket_get_io_channel (client);
int fd = g_io_channel_unix_get_fd (io);
@@ -1978,7 +1979,47 @@ lwp_events_server_cb (GIOChannel *source,
gnet_unix_socket_delete (client);
- client = gnet_unix_socket_server_accept_nonblock (app->lwp_events);
+ client = gnet_unix_socket_server_accept_nonblock (app->lwp_unix);
+ } while (client != NULL);
+
+ if (update) {
+ if (app->client.timeout == NULL)
+ app->client.timeout = _new_timeout (2000, (GSourceFunc) _update_client, app);
+ }
+ }
+
+ if (condition & G_IO_HUP)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+lwp_tcp_server_cb (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data)
+{
+ App *app = data;
+
+ if (condition & G_IO_IN) {
+ GTcpSocket *client;
+ gboolean update = FALSE;
+
+ client = gnet_tcp_socket_server_accept (app->lwp_tcp);
+ do {
+ GIOChannel *io = gnet_tcp_socket_get_io_channel (client);
+ int fd = g_io_channel_unix_get_fd (io);
+ gzFile *file = gzdopen (dup (fd), "r");
+
+ if (lwp_read (file, app)) {
+ update = TRUE;
+ while (lwp_read (file, app)) ;
+ }
+ gzclose (file);
+
+ gnet_tcp_socket_delete (client);
+
+ client = gnet_tcp_socket_server_accept_nonblock (app->lwp_tcp);
} while (client != NULL);
if (update) {
@@ -2296,7 +2337,7 @@ execute_cmdline_lwp (App *app, char **argv, gboolean attach_dbg, GError **error)
return FALSE;
}
- path = gnet_unix_socket_get_path (app->lwp_events);
+ path = gnet_unix_socket_get_path (app->lwp_unix);
n_client_env = 0;
while (argv[n_client_env] != NULL) {
@@ -2467,10 +2508,17 @@ int main
g_remove (path);
/* lwp interface */
- app.lwp_events = gnet_unix_socket_server_new (path);
+ app.lwp_unix = gnet_unix_socket_server_new (path);
g_free (path);
- io = gnet_unix_socket_get_io_channel (app.lwp_events);
- g_io_add_watch (io, G_IO_IN, lwp_events_server_cb, &app);
+ io = gnet_unix_socket_get_io_channel (app.lwp_unix);
+ g_io_add_watch (io, G_IO_IN, lwp_unix_server_cb, &app);
+ g_io_channel_unref (io);
+
+ iface = gnet_inetaddr_get_host_addr ();
+ app.lwp_tcp = gnet_tcp_socket_server_new_full (iface, 5320);
+ gnet_inetaddr_delete (iface);
+ io = gnet_tcp_socket_get_io_channel (app.lwp_tcp);
+ g_io_add_watch (io, G_IO_IN, lwp_tcp_server_cb, &app);
g_io_channel_unref (io);
/* restrict to IPv4 loopback */
@@ -2557,7 +2605,8 @@ int main
_client_fini (&app.client);
- gnet_unix_socket_delete (app.lwp_events);
+ gnet_unix_socket_delete (app.lwp_unix);
+ gnet_tcp_socket_delete (app.lwp_tcp);
gnet_tcp_socket_delete (app.vg_events);
gnet_tcp_socket_delete (app.vg_log);
diff --git a/src/lwp.c b/src/lwp.c
index 3986595..bfe7375 100644
--- a/src/lwp.c
+++ b/src/lwp.c
@@ -36,6 +36,9 @@
#include <sys/un.h>
#include <pthread.h>
#include <stdio.h> /* snprintf */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h> /* gethostbyname */
#include <errno.h>
#include <glib.h> /* types and macros */
@@ -290,8 +293,9 @@ static const char *
_lwp_exe_path (void)
{
static char path[1024];
+ int len;
if (path[0] == '\0')
- readlink ("/proc/self/exe", path, sizeof (path) - 1);
+ len = readlink ("/proc/self/exe", path, sizeof (path) - 1);
return path;
}
@@ -401,7 +405,7 @@ _lwp_write_events (const LWP_EventRecord *events, gushort n_events)
return FALSE;
fd = socket (PF_UNIX, SOCK_STREAM, 0);
- if (fd <0)
+ if (fd < 0)
return FALSE;
memset (&addr, 0, sizeof (addr));
@@ -409,6 +413,52 @@ _lwp_write_events (const LWP_EventRecord *events, gushort n_events)
strcpy (addr.sun_path, env + 5);
if (connect (fd, &addr, sizeof (addr)) < 0)
goto CLEAN_FD;
+ } else if (strncmp (env, "tcp:", 4) == 0) {
+ struct sockaddr_in addr;
+ struct hostent he, *result;
+ const char *colon;
+ char name[256], buf[256];
+ size_t len;
+ int h_err;
+
+ env += 4;
+ colon = strchr (env, ':');
+ if (colon)
+ len = colon - env;
+ else
+ len = strlen (env);
+
+ if (len > sizeof (name) - 1)
+ return FALSE;
+
+ memcpy (name, env, len);
+ name[len] = '\0';
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ if (colon != NULL)
+ addr.sin_port = htons (atoi (colon+1));
+ if (addr.sin_port == 0)
+ addr.sin_port = htons (5320);
+
+ if (! inet_aton (name, &addr.sin_addr)) {
+ if (! gethostbyname_r (name,
+ &he, buf, sizeof (buf), &result, &h_err))
+ {
+ return FALSE;
+ }
+
+ memcpy (&addr.sin_addr.s_addr, result->h_addr_list[0],
+ sizeof (addr.sin_addr.s_addr));
+ }
+
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ return FALSE;
+
+ if (connect (fd, &addr, sizeof (addr)) < 0)
+ goto CLEAN_FD;
} else {
char filename[1024];
snprintf (filename, sizeof (filename), "%s.%d", env, getpid ());
diff --git a/src/procmap-store.c b/src/procmap-store.c
index 08ade14..182af95 100644
--- a/src/procmap-store.c
+++ b/src/procmap-store.c
@@ -283,10 +283,18 @@ procmap_store_sort_by_dirty (gconstpointer A, gconstpointer B)
return b->private_dirty - a->private_dirty;
}
+static gint
+procmap_store_sort_by_addr (gconstpointer A, gconstpointer B)
+{
+ const glibtop_map_entry *a = A, *b = B;
+ return b->start - a->start;
+}
+
static void
procmap_store_init (ProcmapStore *self)
{
- self->sort_func = procmap_store_sort_by_dirty;
+ //self->sort_func = procmap_store_sort_by_dirty;
+ self->sort_func = procmap_store_sort_by_addr;
}
diff --git a/src/procmap.c b/src/procmap.c
index 72853a5..0e6af6e 100644
--- a/src/procmap.c
+++ b/src/procmap.c
@@ -98,6 +98,7 @@ procmap_init (Procmap *self)
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Start",
renderer, "text", PROCMAP_START, NULL);
+ gtk_tree_view_column_set_sort_column_id (column, PROCMAP_START);
gtk_tree_view_append_column (&self->tv, column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("End",
@@ -114,6 +115,7 @@ procmap_init (Procmap *self)
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer,
cell_layout_pretty_print_uint, GUINT_TO_POINTER (PROCMAP_SIZE),
NULL);
+ gtk_tree_view_column_set_sort_column_id (column, PROCMAP_SIZE);
gtk_tree_view_append_column (&self->tv, column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("RSS",
@@ -121,14 +123,16 @@ procmap_init (Procmap *self)
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer,
cell_layout_pretty_print_uint, GUINT_TO_POINTER (PROCMAP_RSS),
NULL);
+ gtk_tree_view_column_set_sort_column_id (column, PROCMAP_RSS);
gtk_tree_view_append_column (&self->tv, column);
renderer = gtk_cell_renderer_text_new ();
- column = gtk_tree_view_column_new_with_attributes ("Private Dirty",
+ column = gtk_tree_view_column_new_with_attributes ("Dirty",
renderer, NULL);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer,
cell_layout_pretty_print_uint, GUINT_TO_POINTER (PROCMAP_PRIVATE_DIRTY),
NULL);
+ gtk_tree_view_column_set_sort_column_id (column, PROCMAP_PRIVATE_DIRTY);
gtk_tree_view_append_column (&self->tv, column);
gtk_tree_view_set_grid_lines (&self->tv, GTK_TREE_VIEW_GRID_LINES_VERTICAL);