예제 #1
0
파일: cache.c 프로젝트: HIPERFIT/mlkit
// ML: string -> cache ptr_option
const cache *
apsml_cacheFind (char *cacheName, request_data *rd)	/*{{{ */
{
//  ppGlobalCache(rd);
  apr_thread_rwlock_rdlock (rd->cachetable->rwlock);
  const cache *c;
//  void **c1 = (void **) &c;
//  ap_log_error(APLOG_MARK, LOG_DEBUG, 0, rd->server, "apsml_cacheFind: cacheName == %s", cacheName);
//  keyNhash kn;
//  kn.key = cacheName;
//  kn.hash = charhashfunction (cacheName);
  if (cachetable_find (rd->cachetable->ht, cacheName, &c) == hash_DNE)
    {
//        ap_log_error(APLOG_MARK, LOG_NOTICE, 0, rd->server, "apsml_cacheFind: cacheName == %s not in main cache", cacheName);
      c = NULL;
    }
//  ap_log_error(APLOG_MARK, LOG_NOTICE, 0, rd->server, "apsml_cacheFind: 2");
  apr_thread_rwlock_unlock (rd->cachetable->rwlock);
  return c;
}				/*}}} */
예제 #2
0
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;
} 
예제 #3
0
파일: switch_apr.c 프로젝트: gujun/sscore
SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_rdlock(switch_thread_rwlock_t *rwlock)
{
	return apr_thread_rwlock_rdlock(rwlock);
}
예제 #4
0
파일: filestat.c 프로젝트: Ga-vin/apache
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);
}
예제 #5
0
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
}
예제 #6
0
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
}
예제 #7
0
파일: cache.c 프로젝트: HIPERFIT/mlkit
// ML : cache * string -> string_ptr
String
apsml_cacheGet (Region rAddr, cache *c, String key1, request_data *rd)	/*{{{ */
{
//  ap_log_error(APLOG_MARK, LOG_DEBUG, 0, rd->server, "apsml_cacheGet 1");
//  ppCache (c, rd);

//  keyNhash kn;
  char *key = &(key1->data);
//  kn.hash = charhashfunction (kn.key);
//  ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//		"apsml_cacheGet: key == %s, hash: %i", kn.key, kn.hash);
  int too_old = 0;
  apr_thread_rwlock_rdlock (c->rwlock);
  apr_proc_mutex_lock(rd->ctx->cachelock.plock);
  unsigned long cachehash = c->hashofname % rd->ctx->cachelock.shmsize;
  unsigned long cacheversion = rd->ctx->cachelock.version[cachehash];
  apr_proc_mutex_unlock(rd->ctx->cachelock.plock);

//  ap_log_error(APLOG_MARK, LOG_DEBUG, 0, rd->server, 
//          "apsml_cacheGet global version: %d, local version %d", cacheversion, c->version);

  if (cacheversion != c->version)
  {
    apr_thread_rwlock_unlock (c->rwlock);
    apsml_cacheFlush(c, rd, 0);
    c->version = cacheversion;
    return (String) NULL;
  }
  entry *entry;
//  void **entry1 = (void **) &entry;
  if (entrytable_find (c->htable, key, &entry) == hash_DNE)
  {
    entry = NULL;
//    ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//	   "apsml_cacheGet: No such thing");
  }
  if (entry)
  {
    // we found an entry 
    // which should be put on top of the list
    // We require locking on the list
    // If time is too old then drop the entry

    time_t ct = time (NULL);
    apr_thread_mutex_lock (c->mutex);

    LINKEDLIST_REMOVE (entry);
    //time_t t = ct < entry->time ? 0 : ct - entry->time;
    if (entry->timeout)
    {
      if (ct > entry->time)
	    {			// entry too old
	      too_old = 1;
	     /* ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
			    "apsml_cacheGet: Entry too old, ct == %ld, entry->time == %ld",
			    ct, entry->time); */
	      LINKEDLIST_INSERTOVER (c->sentinel, entry);
	    }
      else
	    {
	      // keep entry fresh
	      LINKEDLIST_INSERTUNDER (c->sentinel, entry);
//	      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//			    "apsml_cacheGet: Entry fine ct == %i, entry->time == %i",
//			    ct, entry->time);
        cacheheap_heapchangekey(c->heap, entry->heappos, MAX (ct + entry->timeout, entry->time));
	      //entry->time = MAX (ct + entry->timeout, entry->time);
	    }
	  }
    else
    {
	    LINKEDLIST_INSERTUNDER (c->sentinel, entry);
    }
//    ap_log_rerror(APLOG_MARK, LOG_NOTICE, 0, rd->request, "apsml_cacheGetFound: etime: %d, rtime: %d, too_old: %i key: %s, value %d, valuedata: %s", entry->time, time(NULL), too_old, key, entry, entry->data);
     apr_thread_mutex_unlock (c->mutex);
  }
  String s;
  if (too_old == 0 && entry)
  {
    s = convertStringToML (rAddr, entry->data);
  }
  else
  {
    s = (String) NULL;
  }
  apr_thread_rwlock_unlock (c->rwlock);
//    ap_log_rerror(APLOG_MARK, LOG_NOTICE, 0, rd->request, "apsml_cacheGet: Returning");
  return s;
}				/*}}} */