diff options
author | Dave Barach <dave@barachs.net> | 2016-10-13 17:35:09 -0400 |
---|---|---|
committer | Dave Barach <dave@barachs.net> | 2016-10-13 17:36:12 -0400 |
commit | 77378332ac585f0558a640b148bac0308675a459 (patch) | |
tree | 3ead2587c0a6da74d30be37aca84cf683883caa0 | |
parent | 770930c45f9793151e2c39b5834b1c8e7210bbe6 (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.h | 2 | ||||
-rw-r--r-- | vlib-api/vlibmemory/memory_shared.c | 43 |
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 |