aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/vapi
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2020-01-27 16:04:33 +0100
committerAlberto Compagno <acompagn+fdio@cisco.com>2020-01-27 16:56:28 +0100
commitb0768b35fb515b7c0a15c3c7d8c1227497c59786 (patch)
tree1e2b1318f680fffd555ddc26a48e4a4156b06dfc /hicn-plugin/vapi
parentbe54ac541c9700eaa9085bc8b4ee21b7a5f7e30a (diff)
[HICN-488] Adding lock to vapi calls and manage vapi_connect in order to connect only once.
- Added library to hicn-plugin called safe_vapi that takes care of handling concurrent calls to the vapi. - Removed dependency of libhicnctrl from libtransport and added dependency to safe_vapi. - Added dependency to safe_vapi on libhicnctrl Change-Id: Ie49e8319f64a50e7ed6a56e041db977c3b184cc5 Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com>
Diffstat (limited to 'hicn-plugin/vapi')
-rw-r--r--hicn-plugin/vapi/CMakeLists.txt70
-rw-r--r--hicn-plugin/vapi/include/vapi/vapi_safe.h19
-rw-r--r--hicn-plugin/vapi/vapi_safe.c75
3 files changed, 164 insertions, 0 deletions
diff --git a/hicn-plugin/vapi/CMakeLists.txt b/hicn-plugin/vapi/CMakeLists.txt
new file mode 100644
index 000000000..00bcaf49f
--- /dev/null
+++ b/hicn-plugin/vapi/CMakeLists.txt
@@ -0,0 +1,70 @@
+# Copyright (c) 2019 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+set(SAFE_VAPI safe_vapi CACHE INTERNAL "" FORCE)
+set(SAFE_VAPI_SHARED ${SAFE_VAPI}.shared CACHE INTERNAL "" FORCE)
+set(SAFE_VAPI_STATIC ${SAFE_VAPI}.static CACHE INTERNAL "" FORCE)
+
+project(${SAFE_VAPI})
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/Modules/"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules/"
+)
+
+include (Packaging)
+include (BuildMacros)
+
+# Dependencies
+
+find_package(Vpp REQUIRED)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/vapi/vapi_safe.h
+)
+
+list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/vapi_safe.c
+)
+
+set (LIBRARIES
+ ${VPP_LIBRARIES})
+
+list (APPEND INCLUDE_DIRS
+ ${VPP_INCLUDE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+build_library(${SAFE_VAPI}
+ SHARED STATIC
+ SOURCES ${SOURCE_FILES} ${HEADER_FILES}
+ INSTALL_HEADERS ${HEADER_FILES}
+ LINK_LIBRARIES ${LIBRARIES}
+ COMPONENT ${HICN_PLUGIN}
+ INCLUDE_DIRS ${INCLUDE_DIRS}
+ INSTALL_ROOT_DIR /
+ DEFINITIONS ${COMPILER_DEFINITIONS}
+ )
+
+set(SAFE_VAPI_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ "" CACHE INTERNAL
+ "" FORCE
+)
+
+set(SAFE_VAPI_LIBRARIES
+ ${SAFE_VAPI_SHARED}
+ "" CACHE INTERNAL
+ "" FORCE
+)
+
diff --git a/hicn-plugin/vapi/include/vapi/vapi_safe.h b/hicn-plugin/vapi/include/vapi/vapi_safe.h
new file mode 100644
index 000000000..df1114cde
--- /dev/null
+++ b/hicn-plugin/vapi/include/vapi/vapi_safe.h
@@ -0,0 +1,19 @@
+#ifndef VAPI_SAFE
+#include <vapi/vapi.h>
+#include <pthread.h>
+
+extern pthread_mutex_t *mutex;
+
+vapi_error_e vapi_connect_safe(vapi_ctx_t * vapi_ctx_ret, int async);
+
+vapi_error_e vapi_disconnect_safe();
+void vapi_lock();
+
+void vapi_unlock();
+
+#define VAPI_SAFE (NAME, res, ...) \
+ vapi_lock(); \
+ res = ## NAME (__ARGS__); \
+ vapi_unlock();
+
+#endif //VAPI_SAFE
diff --git a/hicn-plugin/vapi/vapi_safe.c b/hicn-plugin/vapi/vapi_safe.c
new file mode 100644
index 000000000..c1d66c0ac
--- /dev/null
+++ b/hicn-plugin/vapi/vapi_safe.c
@@ -0,0 +1,75 @@
+#include <vapi/vapi_safe.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define APP_NAME "hicn_plugin"
+#define MAX_OUTSTANDING_REQUESTS 4
+#define RESPONSE_QUEUE_SIZE 2
+
+pthread_mutex_t *mutex = NULL;
+vapi_ctx_t g_vapi_ctx_instance = NULL;
+u32 count = 0;
+int lock = 0;
+
+vapi_error_e vapi_connect_safe(vapi_ctx_t *vapi_ctx_ret, int async) {
+ vapi_error_e rv = VAPI_OK;
+
+ while (!__sync_bool_compare_and_swap(&lock, 0, 1));
+
+ if (!g_vapi_ctx_instance && !mutex)
+ {
+ rv = vapi_ctx_alloc(&g_vapi_ctx_instance);
+ if (rv != VAPI_OK)
+ goto err;
+
+ mutex = malloc(sizeof(pthread_mutex_t));
+ if (!mutex)
+ goto err_mutex_alloc;
+
+ if (pthread_mutex_init(mutex, NULL) != 0) {
+ printf("Mutex init failed\n");
+ goto err_mutex_init;
+ }
+ }
+
+ if (!count)
+ {
+ rv = vapi_connect(g_vapi_ctx_instance, APP_NAME, NULL,
+ MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE,
+ async ? VAPI_MODE_NONBLOCKING : VAPI_MODE_BLOCKING, true);
+
+ if (rv != VAPI_OK)
+ goto err_vapi;
+
+ count++;
+ }
+
+ *vapi_ctx_ret = g_vapi_ctx_instance;
+
+ while (!__sync_bool_compare_and_swap(&lock, 1, 0));
+ return rv;
+
+ err_vapi:
+ vapi_ctx_free(g_vapi_ctx_instance);
+ err_mutex_init:
+ free(mutex);
+ err_mutex_alloc:
+ err:
+ while (!__sync_bool_compare_and_swap(&lock, 1, 0));
+ return VAPI_ENOMEM;
+}
+
+vapi_error_e vapi_disconnect_safe() {
+ pthread_mutex_lock(mutex);
+ vapi_error_e rv = VAPI_OK;
+ pthread_mutex_unlock(mutex);
+ return rv;
+}
+
+void vapi_lock() {
+ pthread_mutex_lock(mutex);
+}
+
+void vapi_unlock() {
+ pthread_mutex_unlock(mutex);
+}