add xxx_or_null(...) message buffer allocation variants 07/3407/1
authorDave Barach <dave@barachs.net>
Thu, 13 Oct 2016 21:35:09 +0000 (17:35 -0400)
committerDave Barach <dave@barachs.net>
Thu, 13 Oct 2016 21:36:12 +0000 (17:36 -0400)
Useful when attempting to serialize potentially very large data
structures and send them to API clients. NULL pointer checks are
MANDATORY when calling xxx_or_null(...) variant functions.

Change-Id: I6ae272deb7150a2c5aa82ec45a206e5bddee7a02
Signed-off-by: Dave Barach <dave@barachs.net>
vlib-api/vlibmemory/api.h
vlib-api/vlibmemory/memory_shared.c

index bc4cfbf..825891c 100644 (file)
@@ -124,7 +124,9 @@ vl_msg_api_handle_from_index_and_epoch (u32 index, u32 epoch)
 }
 
 void *vl_msg_api_alloc (int nbytes);
+void *vl_msg_api_alloc_or_null (int nbytes);
 void *vl_msg_api_alloc_as_if_client (int nbytes);
+void *vl_msg_api_alloc_as_if_client_or_null (int nbytes);
 void vl_msg_api_free (void *a);
 int vl_map_shmem (char *region_name, int is_vlib);
 void vl_register_mapped_shmem_region (svm_region_t * rp);
index 900e89d..134fcd5 100644 (file)
@@ -40,7 +40,7 @@
 #undef vl_typedefs
 
 static inline void *
-vl_msg_api_alloc_internal (int nbytes, int pool)
+vl_msg_api_alloc_internal (int nbytes, int pool, int may_return_null)
 {
   int i;
   msgbuf_t *rv;
@@ -64,13 +64,15 @@ vl_msg_api_alloc_internal (int nbytes, int pool)
   if (shmem_hdr->vl_rings == 0)
     {
       clib_warning ("vl_rings NULL");
-      return 0;
+      ASSERT (0);
+      abort ();
     }
 
   if (shmem_hdr->client_rings == 0)
     {
       clib_warning ("client_rings NULL");
-      return 0;
+      ASSERT (0);
+      abort ();
     }
 
   ap = pool ? shmem_hdr->vl_rings : shmem_hdr->client_rings;
@@ -123,7 +125,19 @@ vl_msg_api_alloc_internal (int nbytes, int pool)
 
   pthread_mutex_lock (&am->vlib_rp->mutex);
   oldheap = svm_push_data_heap (am->vlib_rp);
-  rv = clib_mem_alloc (nbytes);
+  if (may_return_null)
+    {
+      rv = clib_mem_alloc_or_null (nbytes);
+      if (PREDICT_FALSE (rv == 0))
+       {
+         svm_pop_heap (oldheap);
+         pthread_mutex_unlock (&am->vlib_rp->mutex);
+         return 0;
+       }
+    }
+  else
+    rv = clib_mem_alloc (nbytes);
+
   rv->q = 0;
   svm_pop_heap (oldheap);
   pthread_mutex_unlock (&am->vlib_rp->mutex);
@@ -144,13 +158,30 @@ vl_msg_api_alloc (int nbytes)
    * Clients use pool-0, vlib proc uses pool 1
    */
   pool = (am->our_pid == shmem_hdr->vl_pid);
-  return vl_msg_api_alloc_internal (nbytes, pool);
+  return vl_msg_api_alloc_internal (nbytes, pool, 0 /* may_return_null */ );
+}
+
+void *
+vl_msg_api_alloc_or_null (int nbytes)
+{
+  int pool;
+  api_main_t *am = &api_main;
+  vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
+
+  pool = (am->our_pid == shmem_hdr->vl_pid);
+  return vl_msg_api_alloc_internal (nbytes, pool, 1 /* may_return_null */ );
 }
 
 void *
 vl_msg_api_alloc_as_if_client (int nbytes)
 {
-  return vl_msg_api_alloc_internal (nbytes, 0);
+  return vl_msg_api_alloc_internal (nbytes, 0, 0 /* may_return_null */ );
+}
+
+void *
+vl_msg_api_alloc_as_if_client_or_null (int nbytes)
+{
+  return vl_msg_api_alloc_internal (nbytes, 0, 1 /* may_return_null */ );
 }
 
 void