aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-10-13 17:35:09 -0400
committerDave Barach <dave@barachs.net>2016-10-13 17:36:12 -0400
commit77378332ac585f0558a640b148bac0308675a459 (patch)
tree3ead2587c0a6da74d30be37aca84cf683883caa0
parent770930c45f9793151e2c39b5834b1c8e7210bbe6 (diff)
add xxx_or_null(...) message buffer allocation variants
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>
-rw-r--r--vlib-api/vlibmemory/api.h2
-rw-r--r--vlib-api/vlibmemory/memory_shared.c43
2 files changed, 39 insertions, 6 deletions
diff --git a/vlib-api/vlibmemory/api.h b/vlib-api/vlibmemory/api.h
index bc4cfbf49b3..825891cf9ed 100644
--- a/vlib-api/vlibmemory/api.h
+++ b/vlib-api/vlibmemory/api.h
@@ -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);
diff --git a/vlib-api/vlibmemory/memory_shared.c b/vlib-api/vlibmemory/memory_shared.c
index 900e89d15c3..134fcd52c84 100644
--- a/vlib-api/vlibmemory/memory_shared.c
+++ b/vlib-api/vlibmemory/memory_shared.c
@@ -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