Beispiel #1
0
void * APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data)
{
    int i;

    for (i = 0; i < MAX_COUNTER; i++) {
        apr_thread_rwlock_wrlock(thread_rwlock);
        mutex_counter++;
        apr_thread_rwlock_unlock(thread_rwlock);
    }
    return NULL;
}
Beispiel #2
0
int test_thread_rwlock(int num_threads)
{
    apr_thread_t *t[MAX_THREADS];
    apr_status_t s[MAX_THREADS];
    apr_time_t time_start, time_stop;
    int i;

    mutex_counter = 0;

    printf("apr_thread_rwlock_t Tests\n");
    printf("%-60s", "    Initializing the apr_thread_rwlock_t");
    s[0] = apr_thread_rwlock_create(&thread_rwlock, pool);
    if (s[0] != APR_SUCCESS) {
        printf("Failed!\n");
        return s[0];
    }
    printf("OK\n");

    apr_thread_rwlock_wrlock(thread_rwlock);
    /* set_concurrency(4)? -aaron */
    printf("    Starting %d threads    ", num_threads);
    for (i = 0; i < num_threads; ++i) {
        s[i] = apr_thread_create(&t[i], NULL, thread_rwlock_func, NULL, pool);
        if (s[i] != APR_SUCCESS) {
            printf("Failed!\n");
            return s[i];
        }
    }
    printf("OK\n");

    time_start = apr_time_now();
    apr_thread_rwlock_unlock(thread_rwlock);

    /* printf("%-60s", "    Waiting for threads to exit"); */
    for (i = 0; i < num_threads; ++i) {
        apr_thread_join(&s[i], t[i]);
    }
    /* printf("OK\n"); */

    time_stop = apr_time_now();
    printf("microseconds: %" APR_INT64_T_FMT " usec\n",
           (time_stop - time_start));
    if (mutex_counter != MAX_COUNTER * num_threads)
        printf("error: counter = %ld\n", mutex_counter);

    return APR_SUCCESS;
}
Beispiel #3
0
// ML: string * int * int -> cache ptr_option
const cache *
apsml_cacheCreate (char *key, int maxsize, int timeout, request_data * rd)	/*{{{ */
{
//  keyNhash kn1;
//  kn1.key = &(cacheName1->data);
//  kn1.hash = charhashfunction (kn1.key);
//  char *key = &(cacheName1->data);
  apr_thread_rwlock_wrlock (rd->cachetable->rwlock);
  const cache *c;
//  void **c1 = (void **) &c;
//  ap_log_error (APLOG_MARK, LOG_DEBUG, 0, rd->server,
//    "apsml_cacheCreate: cacheName == %s, maxsize == %i, timeout == %i",
//    &(cacheName1->data), maxsize, timeout);
  if (cachetable_find (rd->cachetable->ht, key, &c) == hash_DNE)
    {
      int size = strlen(key);
      char *kn = malloc (size+1);
//      ap_log_error (APLOG_MARK, LOG_DEBUG, 0, rd->server,
//		    "apsml_cacheCreate: malloc 0x%x, length:%d", (unsigned long) kn, size);
      
      if (kn == NULL) return NULL;
//      kn->key = (char *) (kn + 1);
//      kn->hash = kn1.hash;
      strncpy (kn, key, size);
      kn[size] = 0;
      c = cacheCreate (maxsize, timeout, charhashfunction(kn), rd);
      cachetable_insert (rd->cachetable->ht, kn, c);
    }
  else
    {
      ap_log_error (APLOG_MARK, LOG_DEBUG, 0, rd->server,
		    "apsml_cacheCreate: cacheName == %s already exists", key);
    }
//  ppGlobalCache(rd);
  apr_thread_rwlock_unlock (rd->cachetable->rwlock);
  return c;
}				/*}}} */
static void *APR_THREAD_FUNC thread_rwlock_func(apr_thread_t *thd, void *data)
{
    int exitLoop = 1;

    while (1)
    {
        apr_thread_rwlock_rdlock(rwlock);
        if (i == MAX_ITER)
            exitLoop = 0;
        apr_thread_rwlock_unlock(rwlock);

        if (!exitLoop)
            break;

        apr_thread_rwlock_wrlock(rwlock);
        if (i != MAX_ITER)
        {
            i++;
            x++;
        }
        apr_thread_rwlock_unlock(rwlock);
    }
    return NULL;
} 
Beispiel #5
0
int
apsml_cacheFlush (cache * c, request_data *rd, int global)	/*{{{ */
{
  apr_thread_rwlock_wrlock (c->rwlock);
  if (global)
  {
    apr_proc_mutex_lock(rd->ctx->cachelock.plock);
    unsigned long cachehash = c->hashofname % rd->ctx->cachelock.shmsize;
    rd->ctx->cachelock.version[cachehash]++;
    apr_proc_mutex_unlock(rd->ctx->cachelock.plock);
  }
  while (c->sentinel->down != c->sentinel)
  {
    listremoveitem (c, c->sentinel->down, rd);
  }
  if (entrytable_reinit (c->htable) == hash_OUTOFMEM)
  {
    apr_thread_rwlock_unlock (c->rwlock);
    return 0;
  }
  c->size = c->htable->hashTableSize * sizeof (entrytable_hashelement_t);
  apr_thread_rwlock_unlock (c->rwlock);
  return 1;
}				/*}}} */
Beispiel #6
0
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock)
{
	return apr_thread_rwlock_wrlock(rwlock);
}
Beispiel #7
0
int cstat (NXPathCtx_t ctx, char *path, struct stat *buf, unsigned long requestmap, apr_pool_t *p)
{
    apr_pool_t *gPool = (apr_pool_t *)getGlobalPool();
    apr_hash_t *statCache = NULL;
    apr_thread_rwlock_t *rwlock = NULL;

    NXPathCtx_t pathctx = 0;
    char *ptr = NULL, *tr;
    int len = 0, x;
    char *ppath;
    char *pinfo;

    if (ctx == 1) {

        /* If there isn't a global pool then just stat the file
           and return */
        if (!gPool) {
            char poolname[50];
    
            if (apr_pool_create(&gPool, NULL) != APR_SUCCESS) {
                return getstat(ctx, path, buf, requestmap);
            }
    
            setGlobalPool(gPool);
            apr_pool_tag(gPool, apr_pstrdup(gPool, "cstat_mem_pool"));
    
            statCache = apr_hash_make(gPool);
            apr_pool_userdata_set ((void*)statCache, "STAT_CACHE", stat_cache_cleanup, gPool);

            apr_thread_rwlock_create(&rwlock, gPool);
            apr_pool_userdata_set ((void*)rwlock, "STAT_CACHE_LOCK", apr_pool_cleanup_null, gPool);
        }
        else {
            apr_pool_userdata_get((void**)&statCache, "STAT_CACHE", gPool);
            apr_pool_userdata_get((void**)&rwlock, "STAT_CACHE_LOCK", gPool);
        }

        if (!gPool || !statCache || !rwlock) {
            return getstat(ctx, path, buf, requestmap);
        }
    
        for (x = 0,tr = path;*tr != '\0';tr++,x++) {
            if (*tr == '\\' || *tr == '/') {
                ptr = tr;
                len = x;
            }
            if (*tr == ':') {
                ptr = "\\";
                len = x;
            }
        }
    
        if (ptr) {
            ppath = apr_pstrndup (p, path, len);
            strlwr(ppath);
            if (ptr[1] != '\0') {
                ptr++;
            }
            /* If the path ended in a trailing slash then our result path
               will be a single slash. To avoid stat'ing the root with a
               slash, we need to make sure we stat the current directory
               with a dot */
            if (((*ptr == '/') || (*ptr == '\\')) && (*(ptr+1) == '\0')) {
                pinfo = apr_pstrdup (p, ".");
            }
            else {
                pinfo = apr_pstrdup (p, ptr);
            }
        }
    
        /* If we have a statCache then try to pull the information
           from the cache.  Otherwise just stat the file and return.*/
        if (statCache) {
            apr_thread_rwlock_rdlock(rwlock);
            pathctx = (NXPathCtx_t) apr_hash_get(statCache, ppath, APR_HASH_KEY_STRING);
            apr_thread_rwlock_unlock(rwlock);
            if (pathctx) {
                return getstat(pathctx, pinfo, buf, requestmap);
            }
            else {
                int err;

                err = NXCreatePathContext(0, ppath, 0, NULL, &pathctx);
                if (!err) {
                    apr_thread_rwlock_wrlock(rwlock);
                    apr_hash_set(statCache, apr_pstrdup(gPool,ppath) , APR_HASH_KEY_STRING, (void*)pathctx);
                    apr_thread_rwlock_unlock(rwlock);
                    return getstat(pathctx, pinfo, buf, requestmap);
                }
            }
        }
    }
    return getstat(ctx, path, buf, requestmap);
}
static int ip_in_url_test (request_rec *r, apr_sockaddr_t *ip_to_be_test,
                           REMOTE_INFO *p_remote_info, apr_time_t expire_time)
{
    apr_status_t rv;
    char errmsg_buf[120];

#ifdef DEBUG
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                  "cur_time: %lld | last_contact_time:"
                  " %lld | last_update_time: %s | expire_time: %lld",
                  apr_time_now (), p_remote_info->last_contact_time,
                  p_remote_info->last_update_time, expire_time);
#endif

#if APR_HAS_THREADS
    if (apr_time_now () - p_remote_info->last_contact_time
        >= expire_time) { /* the ip-list from url is expired */
        rv = apr_thread_rwlock_wrlock (p_remote_info->rwlock);
        if (rv != APR_SUCCESS) {
            p_remote_info->last_contact_time = apr_time_now ();
            apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to obtain wrlock: %s", errmsg_buf);
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to update expired data from remote url,"
                          " the ipsubnet-list remains unchanged,"
                          " after remote_expire_time next update"
                          " will be invoked by another request");
        }
        else {
                /* rejudge whether it is necessary to update */
            if (apr_time_now () - p_remote_info->last_contact_time
                >= expire_time) {
                p_remote_info->last_contact_time = apr_time_now ();
                if (update_expired_data_from_remote_info (r, p_remote_info)
                    == -1) {
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                  "fail to update expired data from remote url,"
                                  " the ipsubnet-list remains unchanged,"
                                  " after remote_expire_time next update will"
                                  " be invoked by another request");
                }
            }
            rv = apr_thread_rwlock_unlock (p_remote_info->rwlock);
            if (rv != APR_SUCCESS) {
                apr_strerror (rv, errmsg_buf, sizeof(errmsg_buf));
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              "fail to release wrlock: %s", errmsg_buf);
            }
        }
    }

    rv = apr_thread_rwlock_rdlock (p_remote_info->rwlock);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to obtain rdlock: %s", errmsg_buf);
    }
        /* check if the request's ip is match one of the ipsubnets
         * getting from url */
    int ret = ip_in_ipsubnet_list_test (ip_to_be_test,
                                        p_remote_info->p_ipsubnet_list);
    rv = apr_thread_rwlock_unlock (p_remote_info->rwlock);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to release rdlock: %s", errmsg_buf);
    }
    return ret;

#else
    if (apr_time_now () - p_remote_info->last_contact_time
        >= expire_time) { /* the ip-list from url is expired */
        p_remote_info->last_contact_time = apr_time_now ();
        if (update_expired_data_from_remote_info (r, p_remote_info) == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to update expired data from remote url,"
                                  " the ipsubnet-list remains unchanged,"
                                  " after remote_expire_time next update will"
                                  " be invoked by another request");
        }
    }

        /* check if the request's ip is match one
         * of the ipsubnets getting from url */
    return ip_in_ipsubnet_list_test (ip_to_be_test,
                                     p_remote_info->p_ipsubnet_list);
    
#endif
}
static int ip_in_local_file_test (request_rec *r,
                                  apr_sockaddr_t *ip_to_be_test,
                                  LOCAL_FILE_INFO *p_local_file_info)
{
    apr_status_t rv;
    char errmsg_buf[120];

#if APR_HAS_THREADS
    rv = apr_thread_rwlock_wrlock (p_local_file_info->rwlock);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to obtain wrlock: %s", errmsg_buf);
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to update from local file, "
                      "the ipsubnet-list remains unchanged,"
                      " next update will be invoked by another request");
    }
    else {
        if (update_expired_data_from_local_file_info (r, p_local_file_info)
            == -1) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to update from local file, "
                          "the ipsubnet-list remains unchanged,"
                          " next update will be invoked by another request");
        }
        rv = apr_thread_rwlock_unlock (p_local_file_info->rwlock);
        if (rv != APR_SUCCESS) {
            apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                          "fail to release wrlock: %s", errmsg_buf);
        }
    }
    rv = apr_thread_rwlock_rdlock (p_local_file_info->rwlock);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to obtain rdlock: %s", errmsg_buf);
    }
        /* check if the request's ip is match one of the ipsubnets
         * getting from local file */
    int ret = ip_in_ipsubnet_list_test (ip_to_be_test,
                                        p_local_file_info->p_ipsubnet_list);
    rv = apr_thread_rwlock_unlock (p_local_file_info->rwlock);
    if (rv != APR_SUCCESS) {
        apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf));
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to release rdlock: %s", errmsg_buf);
    }
    return ret;

#else
    if (update_expired_data_from_local_file_info (r, p_local_file_info)
        == -1) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "fail to update from local file, "
                      "the ipsubnet-list remains unchanged,"
                      " next update will be invoked by another request");
    }
        /* check if the request's ip is match one of the
         * ipsubnets getting from url */
    return ip_in_ipsubnet_list_test (ip_to_be_test,
                                     p_local_file_info->p_ipsubnet_list);
    
#endif
}
Beispiel #10
0
// ML: cache * String * String -> (int * string_ptr)
int
apsml_cacheSet (int resultPair, Region sAddr, cache * c, int keyValPair, request_data * rd)	/*{{{ */
{
  // allocate new entry and key,value placeholders
// ppCache(c, rd);
  String key1 = (String) elemRecordML (keyValPair, 0);
  String value1 = (String) elemRecordML (keyValPair, 1);
  time_t timeout = (time_t) elemRecordML (keyValPair, 2);
  char *value = &(value1->data);
  int valuesize = sizeStringDefine(value1);
  char *key = &(key1->data);
  int keysize = sizeStringDefine(key1);
  int size = sizeof (entry) + keysize + 1 + valuesize + 1;
  entry *newentry =
    (entry *) malloc (size);
//      ap_log_error (APLOG_MARK, LOG_DEBUG, 0, rd->server,
//		    "apsml_cacheCreate: malloc 0x%x, length: %d, sizeof(entry): %d, keysize: %d, valuesize: %d, key: %s, val: %s", (unsigned long) newentry, size, sizeof(entry), keysize, valuesize, key, value);
  if (newentry == NULL)
    return 0;
  char *newkey = (char *) (newentry + 1);
  char *newvalue = newkey + (keysize + 1);

  // prepare entry by copy data to my space and set pointers
  strncpy (newkey, key, keysize);
  newkey[keysize] = 0;
  strncpy (newvalue, value, valuesize);
  newvalue[valuesize] = 0;
  newentry->key = newkey;
//  newentry->key.hash = charhashfunction (newkey);
  newentry->data = newvalue;
  newentry->size = keysize + valuesize + sizeof (entry) + 2;
  time_t ct = time (NULL);
  if (timeout && c->timeout)
  {
    newentry->timeout = MIN (timeout, c->timeout);
  }
  else if (timeout)
  {
    newentry->timeout = timeout;
  }
  else
  {
    newentry->timeout = c->timeout;
  }
  newentry->time = ct + newentry->timeout;

  // We are going in !!! (as we get a writes lock we have 
  // complete control [no more locks])
  apr_thread_rwlock_wrlock (c->rwlock);
  int tmpsize = c->htable->hashTableSize;
  entry *oldentry = NULL;
//  void **oldentry1 = (void **) &oldentry;
//  ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//		"apsml_cacheSet: key %s, hash: %i", key, newentry->key.hash);
  if (entrytable_find (c->htable, newentry->key, &oldentry) == hash_DNE)
  {
    // No old entry with that key 
    if ((newentry->timeout == -1 
            && cacheheap_heapinsert(c->heap, newentry, (time_t) 0) == heap_OUTOFMEM) 
        || (newentry->timeout && newentry->timeout != (time_t) -1
            && cacheheap_heapinsert(c->heap, newentry, newentry->time) == heap_OUTOFMEM))
    {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received heap_OUTOFMEM", rd->ctx->pid);
      free(newentry);
      newentry = 0;
    }
    if (newentry && entrytable_insert (c->htable, newentry->key, newentry) == hash_OUTOFMEM)
	  {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received hash_OUTOFMEM", rd->ctx->pid);
	    free (newentry);
	    newentry = 0;
	  }
//  ppCache(c, rd);
    oldentry = 0;
  }
  else
  {
    // Old exists
    if ((newentry->timeout == (time_t) -1 
           && cacheheap_heapinsert(c->heap, newentry, (time_t) 0) == heap_OUTOFMEM)
        || (newentry->timeout && newentry->timeout != (time_t) -1
           && cacheheap_heapinsert(c->heap, newentry, newentry->time) == heap_OUTOFMEM))
    {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received heap_OUTOFMEM", rd->ctx->pid);
      free(newentry);
      newentry = 0;
    }
    if (newentry && entrytable_update (c->htable, newentry->key, newentry) == hash_OUTOFMEM)
	  {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received hash_OUTOFMEM", rd->ctx->pid);
	    free (newentry);
	    newentry = 0;
	  }
  }

  if (newentry)
  {
    c->size += newentry->size;
    c->size += (tmpsize - c->htable->hashTableSize) * sizeof (entrytable_hashelement_t);
  }
//  ppCache(c, rd);
  int too_old = 0;
  if (oldentry)
  {
    // Old entry needs removel
    // time_t t = (ct - oldentry->time) < 0 ? 0 : ct - oldentry->time;
    if (oldentry->timeout && ct > oldentry->time)
	  {
	    too_old = 1;
	    second (resultPair) = 0;
	  }
    else
    {
      second (resultPair) = (int) convertStringToML (sAddr, oldentry->data);
    }
    listremoveitem (c, oldentry, rd);
  }
  if (too_old)
    oldentry = 0;
  if (newentry)
    LINKEDLIST_INSERTUNDER (c->sentinel, newentry);
  // I think we are done now
//  ppCache(c, rd);
  entry *curentry;
//  ap_log_error(APLOG_MARK, LOG_NOTICE, 0, rd->server, 
//          "apsml_cacheSet: size %d, maxsize = %d, ct: %d", c->size, c->maxsize, ct);
  while (cacheheap_heapminimal(c->heap, &curentry) != heap_UNDERFLOW)
  {
    if (curentry->time < ct)
    {
      cacheremoveitem(c, curentry, rd);
    }
    else break;
  }
//  ppCache(c, rd);
  if (c->maxsize != -1)
  {
    while (c->size > c->maxsize)
    {
      curentry = c->sentinel->up;
      if (curentry == c->sentinel)
        break;
      cacheremoveitem (c, curentry, rd);
    }
  }
  apr_thread_rwlock_unlock (c->rwlock);
//  ppCache(c, rd);
  if (oldentry && newentry)
    {
      first (resultPair) = 1;
      return resultPair;
    }
  second (resultPair) = 0;
  if (newentry)
    {
      first (resultPair) = 2;
      return resultPair;
    }
  first (resultPair) = 0;
  return resultPair;
}				/*}}} */