Introduce pass_object_as_shm().
authorAndre Noll <maan@systemlinux.org>
Mon, 24 Mar 2008 15:04:21 +0000 (16:04 +0100)
committerAndre Noll <maan@systemlinux.org>
Mon, 24 Mar 2008 15:04:21 +0000 (16:04 +0100)
This singles out the code for passing data from the callback
to the command handler. The plan is to change the callbacks
so that they call this function whenever the result buffer
is too large to fit into a shared memory area.

afs.c

diff --git a/afs.c b/afs.c
index 9b6cd0c4d4d9cffb10f7699bacebf94d73e19728..d41a518d791f9908b0230beda99849f0a8f4c3e9 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -798,18 +798,47 @@ static void command_pre_select(struct sched *s, struct task *t)
        t->ret = 1;
 }
 
+int pass_object_as_shm(int fd, struct osl_object *obj)
+{
+       int ret, shmid;
+       void *shm;
+       struct callback_result *cr;
+
+       if (!obj->data || !obj->size)
+               return 0;
+       ret = shm_new(obj->size + sizeof(struct callback_result));
+       if (ret < 0)
+               return ret;
+       shmid = ret;
+       ret = shm_attach(shmid, ATTACH_RW, &shm);
+       if (ret < 0)
+               goto err;
+       cr = shm;
+       cr->result_size = obj->size;
+       memcpy(shm + sizeof(*cr), obj->data, obj->size);
+       ret = shm_detach(shm);
+       if (ret < 0)
+               goto err;
+       ret = send_bin_buffer(fd, (char *)&shmid, sizeof(int));
+       if (ret >= 0)
+               return ret;
+err:
+       if (shm_destroy(shmid) < 0)
+               PARA_ERROR_LOG("destroy result failed\n");
+       return ret;
+}
+
 /*
  * On errors, negative value is written to fd.
  * On success: If query produced a result, the result_shmid is written to fd.
  * Otherwise, zero is written.
  */
-static int call_callback(int fd, int query_shmid)
+static void call_callback(int fd, int query_shmid)
 {
-       void *query_shm, *result_shm;
+       void *query_shm;
        struct callback_query *cq;
-       struct callback_result *cr;
        struct osl_object query, result = {.data = NULL};
-       int result_shmid = -1, ret, ret2;
+       int ret;
 
        ret = shm_attach(query_shmid, ATTACH_RW, &query_shm);
        if (ret < 0)
@@ -818,39 +847,13 @@ static int call_callback(int fd, int query_shmid)
        query.data = (char *)query_shm + sizeof(*cq);
        query.size = cq->query_size;
        ret = cq->handler(&query, &result);
-       ret2 = shm_detach(query_shm);
-       if (ret2 < 0 && ret >= 0)
-               ret = ret2;
-       if (ret < 0)
-               goto out;
-       ret = 0;
-       if (!result.data || !result.size)
-               goto out;
-       ret = shm_new(result.size + sizeof(struct callback_result));
-       if (ret < 0)
-               goto out;
-       result_shmid = ret;
-       ret = shm_attach(result_shmid, ATTACH_RW, &result_shm);
-       if (ret < 0)
-               goto out;
-       cr = result_shm;
-       cr->result_size = result.size;
-       memcpy(result_shm + sizeof(*cr), result.data, result.size);
-       ret = shm_detach(result_shm);
        if (ret < 0)
                goto out;
-       ret = result_shmid;
+       ret = pass_object_as_shm(fd, &result);
 out:
        free(result.data);
-       ret2 = send_bin_buffer(fd, (char *)&ret, sizeof(int));
-       if (ret < 0 || ret2 < 0) {
-               if (result_shmid >= 0)
-                       if (shm_destroy(result_shmid) < 0)
-                               PARA_ERROR_LOG("destroy result failed\n");
-               if (ret >= 0)
-                       ret = ret2;
-       }
-       return ret;
+       if (ret < 0)
+               PARA_ERROR_LOG("%s\n", para_strerror(-ret));
 }
 
 static void execute_server_command(void)
@@ -905,7 +908,6 @@ static void execute_afs_command(int fd, uint32_t expected_cookie)
                        query_shmid);
                return;
        }
-       /* Ignore return value: Errors might be OK here. */
        call_callback(fd, query_shmid);
 }