File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / tests / libtest / lib1541.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:16 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    1: /***************************************************************************
    2:  *                                  _   _ ____  _
    3:  *  Project                     ___| | | |  _ \| |
    4:  *                             / __| | | | |_) | |
    5:  *                            | (__| |_| |  _ <| |___
    6:  *                             \___|\___/|_| \_\_____|
    7:  *
    8:  * Copyright (C) 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
    9:  *
   10:  * This software is licensed as described in the file COPYING, which
   11:  * you should have received as part of this distribution. The terms
   12:  * are also available at https://curl.haxx.se/docs/copyright.html.
   13:  *
   14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
   15:  * copies of the Software, and permit persons to whom the Software is
   16:  * furnished to do so, under the terms of the COPYING file.
   17:  *
   18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
   19:  * KIND, either express or implied.
   20:  *
   21:  ***************************************************************************/
   22: #include "test.h"
   23: 
   24: #include "testutil.h"
   25: #include "warnless.h"
   26: #include "memdebug.h"
   27: 
   28: #ifdef HAVE_PTHREAD_H
   29: #include <pthread.h>
   30: #include <time.h>
   31: 
   32: /* number of threads to fire up in parallel */
   33: #define NUM_THREADS 67
   34: 
   35: /* for how many seconds each thread will loop */
   36: #define RUN_FOR_SECONDS 7
   37: 
   38: static pthread_mutex_t connlock;
   39: 
   40: static size_t write_db(void *ptr, size_t size, size_t nmemb, void *data)
   41: {
   42:   /* not interested in the downloaded bytes, return the size */
   43:   (void)ptr;  /* unused */
   44:   (void)data; /* unused */
   45:   return (size_t)(size * nmemb);
   46: }
   47: 
   48: static void lock_cb(CURL *handle, curl_lock_data data,
   49:                     curl_lock_access access, void *userptr)
   50: {
   51:   (void)access; /* unused */
   52:   (void)userptr; /* unused */
   53:   (void)handle; /* unused */
   54:   (void)data; /* unused */
   55:   pthread_mutex_lock(&connlock);
   56: }
   57: 
   58: static void unlock_cb(CURL *handle, curl_lock_data data,
   59:                       void *userptr)
   60: {
   61:   (void)userptr; /* unused */
   62:   (void)handle;  /* unused */
   63:   (void)data;    /* unused */
   64:   pthread_mutex_unlock(&connlock);
   65: }
   66: 
   67: static void init_locks(void)
   68: {
   69:   pthread_mutex_init(&connlock, NULL);
   70: }
   71: 
   72: static void kill_locks(void)
   73: {
   74:   pthread_mutex_destroy(&connlock);
   75: }
   76: 
   77: struct initurl {
   78:   const char *url;
   79:   CURLSH *share;
   80:   int threadno;
   81: };
   82: 
   83: static void *run_thread(void *ptr)
   84: {
   85:   struct initurl *u = (struct initurl *)ptr;
   86:   int i;
   87:   time_t end = time(NULL) + RUN_FOR_SECONDS;
   88: 
   89:   for(i = 0; time(NULL) < end; i++) {
   90:     CURL *curl = curl_easy_init();
   91:     curl_easy_setopt(curl, CURLOPT_URL, u->url);
   92:     curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
   93:     curl_easy_setopt(curl, CURLOPT_SHARE, u->share);
   94:     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_db);
   95:     curl_easy_perform(curl); /* ignores error */
   96:     curl_easy_cleanup(curl);
   97:     fprintf(stderr, "Thread %d transfer %d\n", u->threadno, i);
   98:   }
   99: 
  100:   return NULL;
  101: }
  102: 
  103: int test(char *URL)
  104: {
  105:   pthread_t tid[NUM_THREADS];
  106:   int i;
  107:   CURLSH *share;
  108:   struct initurl url[NUM_THREADS];
  109: 
  110:   /* Must initialize libcurl before any threads are started */
  111:   curl_global_init(CURL_GLOBAL_ALL);
  112: 
  113:   share = curl_share_init();
  114:   curl_share_setopt(share, CURLSHOPT_LOCKFUNC, lock_cb);
  115:   curl_share_setopt(share, CURLSHOPT_UNLOCKFUNC, unlock_cb);
  116:   curl_share_setopt(share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
  117: 
  118:   init_locks();
  119: 
  120:   for(i = 0; i< NUM_THREADS; i++) {
  121:     int error;
  122:     url[i].url = URL;
  123:     url[i].share = share;
  124:     url[i].threadno = i;
  125:     error = pthread_create(&tid[i], NULL, run_thread, &url[i]);
  126:     if(0 != error)
  127:       fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
  128:     else
  129:       fprintf(stderr, "Thread %d, gets %s\n", i, URL);
  130:   }
  131: 
  132:   /* now wait for all threads to terminate */
  133:   for(i = 0; i< NUM_THREADS; i++) {
  134:     pthread_join(tid[i], NULL);
  135:     fprintf(stderr, "Thread %d terminated\n", i);
  136:   }
  137: 
  138:   kill_locks();
  139: 
  140:   curl_share_cleanup(share);
  141:   curl_global_cleanup();
  142:   return 0;
  143: }
  144: 
  145: #else /* without pthread, this test doesn't work */
  146: int test(char *URL)
  147: {
  148:   (void)URL;
  149:   return 0;
  150: }
  151: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>