You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2020/03/04 19:11:55 UTC

[celix] branch develop updated: Refactors curl read and add code for manual unrolling. (#160)

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to refs/heads/develop by this push:
     new 8c956d8  Refactors curl read and add code for manual unrolling. (#160)
8c956d8 is described below

commit 8c956d842a59fb9d5e447ff26d8acd25ae3bb837
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Wed Mar 4 20:11:46 2020 +0100

    Refactors curl read and add code for manual unrolling. (#160)
    
    * Refactors curl read and add code for manual unrolling.
    
    Note the manual unrolling does not have the desired effect on OSX, so
    for now it its commented out.
    
    * Replaces loop with memcpy
    
    * Applying rsa patch for curl sharing of data, cookie & dns
    
    * Removes unused (empty) macro
---
 .../src/remote_service_admin_dfi.c                 | 93 +++++++++++++++++++---
 1 file changed, 82 insertions(+), 11 deletions(-)

diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
index c95bdf4..71f337a 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
+++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
@@ -72,6 +72,10 @@ struct remote_service_admin {
     struct mg_context *ctx;
 
     FILE *logFile;
+    void *curlShare;
+    pthread_mutex_t curlMutexConnect;
+    pthread_mutex_t curlMutexCookie;
+    pthread_mutex_t curlMutexDns;
 };
 
 struct post {
@@ -107,6 +111,47 @@ static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nme
 static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp);
 static void remoteServiceAdmin_log(remote_service_admin_t *admin, int level, const char *file, int line, const char *msg, ...);
 
+static void remoteServiceAdmin_curlshare_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess, void *userptr)
+{
+    (void)handle;
+    (void)data;
+    (void)laccess;
+    remote_service_admin_t *rsa = userptr;
+    switch(data) {
+        case CURL_LOCK_DATA_CONNECT:
+            pthread_mutex_lock(&rsa->curlMutexConnect);
+            break;
+        case CURL_LOCK_DATA_COOKIE:
+            pthread_mutex_lock(&rsa->curlMutexCookie);
+            break;
+        case CURL_LOCK_DATA_DNS:
+            pthread_mutex_lock(&rsa->curlMutexDns);
+            break;
+        default:
+            break;
+    }
+}
+
+static void remoteServiceAdmin_curlshare_unlock(CURL *handle, curl_lock_data data, void *userptr)
+{
+    (void)handle;
+    (void)data;
+    remote_service_admin_t *rsa = userptr;
+    switch(data) {
+        case CURL_LOCK_DATA_CONNECT:
+            pthread_mutex_unlock(&rsa->curlMutexConnect);
+            break;
+        case CURL_LOCK_DATA_COOKIE:
+            pthread_mutex_unlock(&rsa->curlMutexCookie);
+            break;
+        case CURL_LOCK_DATA_DNS:
+            pthread_mutex_unlock(&rsa->curlMutexDns);
+            break;
+        default:
+            break;
+    }
+}
+
 celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote_service_admin_t **admin) {
     celix_status_t status = CELIX_SUCCESS;
 
@@ -153,6 +198,30 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote
             free(detectedIp);
         }
 
+        (*admin)->curlShare = curl_share_init();
+        curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
+        curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+        curl_share_setopt((*admin)->curlShare, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
+        curl_share_setopt((*admin)->curlShare, CURLSHOPT_USERDATA, *admin);
+
+        curl_share_setopt((*admin)->curlShare, CURLSHOPT_LOCKFUNC, remoteServiceAdmin_curlshare_lock);
+        curl_share_setopt((*admin)->curlShare, CURLSHOPT_UNLOCKFUNC, remoteServiceAdmin_curlshare_unlock);
+
+        if(status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexConnect, NULL) != 0) {
+            fprintf(stderr, "Could not initialize mutex connect\n");
+            status = EPERM;
+        }
+
+        if(status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexCookie, NULL) != 0) {
+            fprintf(stderr, "Could not initialize mutex cookie\n");
+            status = EPERM;
+        }
+
+        if(status == CELIX_SUCCESS && pthread_mutex_init(&(*admin)->curlMutexDns, NULL) != 0) {
+            fprintf(stderr, "Could not initialize mutex dns\n");
+            status = EPERM;
+        }
+
         // Prepare callbacks structure. We have only one callback, the rest are NULL.
         struct mg_callbacks callbacks;
         memset(&callbacks, 0, sizeof(callbacks));
@@ -208,6 +277,10 @@ celix_status_t remoteServiceAdmin_destroy(remote_service_admin_t **admin)
     free((*admin)->ip);
     free((*admin)->port);
     free(*admin);
+    curl_share_cleanup((*admin)->curlShare);
+    pthread_mutex_destroy(&(*admin)->curlMutexConnect);
+    pthread_mutex_destroy(&(*admin)->curlMutexCookie);
+    pthread_mutex_destroy(&(*admin)->curlMutexDns);
 
     *admin = NULL;
 
@@ -749,6 +822,7 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description
         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
         curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
+        curl_easy_setopt(curl, CURLOPT_SHARE, rsa->curlShare);
         //logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
         res = curl_easy_perform(curl);
 
@@ -763,18 +837,15 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description
 
 static size_t remoteServiceAdmin_readCallback(void *voidBuffer, size_t size, size_t nmemb, void *userp) {
     struct post *post = userp;
-    char *buffer = voidBuffer;
-
-    if (post->read == post->size) {
-        return 0;
-    } else {
-        size_t buffSize = size * nmemb;
-        size_t startRead = post->read;
-        for (size_t i = 0; i < buffSize && post->size != post->read; ++i) {
-            buffer[i] = post->readptr[post->read++];
-        }
-        return post->read - startRead;
+    size_t buffSize = size * nmemb;
+    size_t readSize = post->size - post->read;
+    if (readSize > buffSize) {
+        readSize = buffSize;
     }
+    void *startRead = (void*)(post->readptr + post->read);
+    memcpy(voidBuffer, startRead, readSize);
+    post->read += readSize;
+    return readSize;
 }
 
 static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {