More error handling.

This commit is contained in:
Søren Sandmann Pedersen
2009-11-02 13:52:11 -05:00
parent 71f2cd3a64
commit ef2da92b0a
2 changed files with 31 additions and 25 deletions

View File

@ -287,45 +287,46 @@ on_read (gpointer data)
} }
} }
/* FIXME: return proper errors */ static void *
#define fail(x) \ fail (GError **err, const char *what)
do { \ {
perror (x); \ g_set_error (err, COLLECTOR_ERROR, COLLECTOR_ERROR_FAILED,
exit (-1); \ "%s: %s", what, strerror (errno));
} while (0)
return NULL;
}
static void * static void *
map_buffer (counter_t *counter, GError **err) map_buffer (counter_t *counter, GError **err)
{ {
int n_bytes = N_PAGES * get_page_size(); int n_bytes = N_PAGES * get_page_size();
void *address, *a; void *address, *a;
/* We use the old trick of mapping the ring buffer twice /* We map the ring buffer twice in consecutive address space,
* consecutively, so that we don't need special-case code * so that we don't need special-case code to deal with wrapping.
* to deal with wrapping.
*/ */
address = mmap (NULL, n_bytes * 2 + get_page_size(), PROT_NONE, address = mmap (NULL, n_bytes * 2 + get_page_size(), PROT_NONE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (address == MAP_FAILED) if (address == MAP_FAILED)
fail ("mmap"); return fail (err, "mmap");
a = mmap (address + n_bytes, n_bytes + get_page_size(), a = mmap (address + n_bytes, n_bytes + get_page_size(),
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FIXED, counter->fd, 0); MAP_SHARED | MAP_FIXED, counter->fd, 0);
if (a != address + n_bytes) if (a != address + n_bytes)
fail ("mmap"); return fail (err, "mmap");
a = mmap (address, n_bytes + get_page_size(), a = mmap (address, n_bytes + get_page_size(),
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FIXED, counter->fd, 0); MAP_SHARED | MAP_FIXED, counter->fd, 0);
if (a == MAP_FAILED) if (a == MAP_FAILED || a != address)
fail ("mmap"); return fail (err, "mmap");
if (a != address) if (a != address)
fail ("mmap"); return fail (err, "mmap");
return address; return address;
} }
@ -370,20 +371,14 @@ counter_new (Collector *collector,
} }
if (fd < 0) if (fd < 0)
{ return fail (err, "Could not open performance counter");
g_set_error (err, COLLECTOR_ERROR, COLLECTOR_ERROR_CANT_OPEN_COUNTER,
"Could not open performance counter: %s\n",
strerror (errno));
return NULL;
}
counter->collector = collector; counter->collector = collector;
counter->fd = fd; counter->fd = fd;
counter->mmap_page = map_buffer (counter, err); counter->mmap_page = map_buffer (counter, err);
if (counter->mmap_page == MAP_FAILED) if (!counter->mmap_page || counter->mmap_page == MAP_FAILED)
return NULL; return NULL;
counter->data = (uint8_t *)counter->mmap_page + get_page_size (); counter->data = (uint8_t *)counter->mmap_page + get_page_size ();
@ -670,6 +665,18 @@ collector_start (Collector *collector,
{ {
counter_t *counter = counter_new (collector, i, err); counter_t *counter = counter_new (collector, i, err);
if (!counter)
{
GList *list;
for (list = collector->counters; list != NULL; list = list->next)
counter_free (list->data);
collector->tracker = NULL;
return FALSE;
}
collector->counters = g_list_append (collector->counters, counter); collector->counters = g_list_append (collector->counters, counter);
} }

View File

@ -30,8 +30,7 @@ GQuark collector_error_quark (void);
typedef enum typedef enum
{ {
COLLECTOR_ERROR_CANT_OPEN_FILE, COLLECTOR_ERROR_FAILED
COLLECTOR_ERROR_CANT_OPEN_COUNTER
} CollectorError; } CollectorError;
/* callback is called whenever a new sample arrives */ /* callback is called whenever a new sample arrives */