static apr_status_t wd_startup(ap_watchdog_t *w, apr_pool_t *p)
{
    apr_status_t rc;

    /* Create thread startup mutex */
    rc = apr_thread_mutex_create(&w->startup, APR_THREAD_MUTEX_UNNESTED, p);
    if (rc != APR_SUCCESS)
        return rc;

    if (w->singleton) {
        /* Initialize singleton mutex in child */
        rc = apr_proc_mutex_child_init(&w->mutex,
                                       apr_proc_mutex_lockfile(w->mutex), p);
        if (rc != APR_SUCCESS)
            return rc;
    }

    /* This mutex fixes problems with a fast start/fast end, where the pool
     * cleanup was being invoked before the thread completely spawned.
     */
    apr_thread_mutex_lock(w->startup);
    apr_pool_pre_cleanup_register(p, w, wd_worker_cleanup);

    /* Start the newly created watchdog */
    rc = apr_thread_create(&w->thread, NULL, wd_worker, w, p);
    if (rc) {
        apr_pool_cleanup_kill(p, w, wd_worker_cleanup);
    }

    apr_thread_mutex_lock(w->startup);
    apr_thread_mutex_unlock(w->startup);
    apr_thread_mutex_destroy(w->startup);

    return rc;
}
Example #2
0
apr_status_t h2_beam_create(h2_bucket_beam **pbeam, apr_pool_t *red_pool, 
                            int id, const char *tag, 
                            apr_size_t max_buf_size)
{
    h2_bucket_beam *beam;
    apr_status_t status = APR_SUCCESS;
    
    beam = apr_pcalloc(red_pool, sizeof(*beam));
    if (!beam) {
        return APR_ENOMEM;
    }

    beam->id = id;
    beam->tag = tag;
    H2_BLIST_INIT(&beam->red);
    H2_BLIST_INIT(&beam->hold);
    H2_BLIST_INIT(&beam->purge);
    H2_BPROXY_LIST_INIT(&beam->proxies);
    beam->red_pool = red_pool;
    beam->max_buf_size = max_buf_size;

    apr_pool_pre_cleanup_register(red_pool, beam, beam_cleanup);
    *pbeam = beam;
    
    return status;
}
Example #3
0
AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data()
{
    if (!retained_data) {
        retained_data = ap_retained_data_create("ap_unixd_mpm_retained_data",
                                                sizeof(*retained_data));
        apr_pool_pre_cleanup_register(ap_pglobal, NULL, retained_data_cleanup);
        retained_data->mpm_state = AP_MPMQ_STARTING;
    }
    return retained_data;
}
APU_DECLARE(apr_status_t) apr_thread_pool_create(apr_thread_pool_t ** me,
                                                 apr_size_t init_threads,
                                                 apr_size_t max_threads,
                                                 apr_pool_t * pool)
{
    apr_thread_t *t;
    apr_status_t rv = APR_SUCCESS;
    apr_thread_pool_t *tp;

    *me = NULL;
    tp = apr_pcalloc(pool, sizeof(apr_thread_pool_t));

    /*
     * This pool will be used by different threads. As we cannot ensure that
     * our caller won't use the pool without acquiring the mutex, we must
     * create a new sub pool.
     */
    rv = apr_pool_create(&tp->pool, pool);
    if (APR_SUCCESS != rv)
        return rv;
    rv = thread_pool_construct(tp, init_threads, max_threads);
    if (APR_SUCCESS != rv)
        return rv;
    apr_pool_pre_cleanup_register(tp->pool, tp, thread_pool_cleanup);

    while (init_threads) {
        /* Grab the mutex as apr_thread_create() and thread_pool_func() will 
         * allocate from (*me)->pool. This is dangerous if there are multiple 
         * initial threads to create.
         */
        apr_thread_mutex_lock(tp->lock);
        ++tp->spawning_cnt;
        rv = apr_thread_create(&t, NULL, thread_pool_func, tp, tp->pool);
        apr_thread_mutex_unlock(tp->lock);
        if (APR_SUCCESS != rv) {
            break;
        }
        tp->thd_cnt++;
        if (tp->thd_cnt > tp->thd_high) {
            tp->thd_high = tp->thd_cnt;
        }
        --init_threads;
    }

    if (rv == APR_SUCCESS) {
        *me = tp;
    }

    return rv;
}
Example #5
0
/**
 * Creates a structure for the server configuration
 * @param p The pool used to allocate memory
 * @param s Information about the virtual server being configured
 * @return A clean dav_ns_server_conf instance
 */
static void *dav_ns_create_server_config(apr_pool_t *p, server_rec *s)
{
  dav_ns_server_conf *conf = apr_pcalloc(p, sizeof(dav_ns_server_conf));

  /* Set defaults */
  conf->type = DAV_NS_NODE_HEAD;

  /* Create plugin manager */
  conf->manager = dmlite_manager_new();
  apr_pool_pre_cleanup_register(p, conf->manager,
                                (apr_status_t(*)(void*))dmlite_manager_free);

  return conf;
}
Example #6
0
apr_bucket *h2_bucket_eos_create(apr_bucket_alloc_t *list,
                                 h2_stream *stream)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    b = h2_bucket_eos_make(b, stream);
    if (stream) {
        h2_bucket_eos *h = b->data;
        apr_pool_pre_cleanup_register(stream->pool, &h->stream, bucket_cleanup);
    }
    return b;
}
Example #7
0
celix_status_t consumingDriver_create(bundle_context_pt context, apr_pool_t *pool, consuming_driver_pt *driver) {
	celix_status_t status = CELIX_SUCCESS;
	(*driver) = apr_palloc(pool, sizeof(**driver));
	if ((*driver) != NULL) {
		(*driver)->pool=pool;
		(*driver)->context=context;
		(*driver)->references=NULL;

		status = arrayList_create(&(*driver)->references);

		apr_pool_pre_cleanup_register(pool, (*driver), consumingDriver_cleanup);
	} else {
		status = CELIX_ENOMEM;
	}
	return status;
}
Example #8
0
static apr_status_t
_create_shm_if_needed(char *shm_path, server_rec *server, apr_pool_t *plog)
{
	apr_pool_t *ppool = server->process->pool;
	apr_shm_t *shm = NULL;
	apr_status_t rc;

	// Test if an SHM segment already exists
	apr_pool_userdata_get((void**)&shm, SHM_HANDLE_KEY, ppool);
	if (shm == NULL) {
		DAV_DEBUG_POOL(plog, 0, "%s: Creating SHM segment at [%s]",
				__FUNCTION__, shm_path);
		// Create a new SHM segment
		rc = apr_shm_create(&shm, sizeof(struct shm_stats_s), shm_path, ppool);
		if (rc != APR_SUCCESS) {
			char buff[256];
			DAV_ERROR_POOL(plog, 0, "Failed to create the SHM segment at [%s]: %s",
					shm_path, apr_strerror(rc, buff, sizeof(buff)));
			return rc;
		}
		/* Init the SHM */
		void *ptr_counter = apr_shm_baseaddr_get(shm);
		if (ptr_counter) {
			memset(ptr_counter, 0, sizeof(struct shm_stats_s));
			/* init rrd's */
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_req_sec));
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_duration));
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_req_put_sec));
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_put_duration));
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_req_get_sec));
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_get_duration));
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_req_del_sec));
			rawx_stats_rrd_init(&(((struct shm_stats_s *) ptr_counter)->body.rrd_del_duration));
		}
		// Save the SHM handle in the process' pool, without cleanup callback
		apr_pool_userdata_set(shm, SHM_HANDLE_KEY, NULL, ppool);
		// Register the cleanup callback to be executed BEFORE pool cleanup
		apr_pool_pre_cleanup_register(ppool, shm, _destroy_shm_cb);
	} else {
		DAV_DEBUG_POOL(plog, 0, "%s: Found an already created SHM segment",
				__FUNCTION__);
	}
	return APR_SUCCESS;
}
Example #9
0
celix_status_t driverMatcher_create(apr_pool_t *pool, bundle_context_pt context, driver_matcher_pt *matcher) {
	celix_status_t status = CELIX_SUCCESS;

	*matcher = apr_palloc(pool, sizeof(**matcher));
	if (!*matcher) {
		status = CELIX_ENOMEM;
	} else {
		apr_pool_pre_cleanup_register(pool, *matcher, driverMatcher_destroy);

		(*matcher)->pool = pool;
		(*matcher)->matches = NULL;
		(*matcher)->context = context;
		(*matcher)->attributes = hashMap_create(driverMatcher_matchKeyHash, NULL, driverMatcher_matchKeyEquals, NULL);

		arrayList_create(&(*matcher)->matches);
	}

	return status;
}
Example #10
0
/**
 * This function is used internally to create new resources.
 * @param r          The request to associate.
 * @param sfn        The SFN to link to the resource.
 * @param uri        The URI (without the query!)
 * @param user       The associated user. If NULL, will be queried and initialized.
 * @param resource   Where to put it.
 * @return           NULL on success.
 */
static dav_error *dav_ns_internal_get_resource(request_rec          *r,
                                               const char           *sfn,
                                               dmlite_credentials   *user,
                                               dav_resource        **resource)
{
  dav_resource_private *info;
  int                   exists, i;
  const char           *p;
  apr_table_t          *query;
  char                  replica_key[10];
  unsigned              nargs;

  /* Initialize info */
  info = apr_pcalloc(r->pool, sizeof(dav_resource_private));
  info->stat.extra = dmlite_any_dict_new();
  apr_pool_pre_cleanup_register(r->pool, info->stat.extra,
                                (apr_status_t(*)(void*))dmlite_any_dict_free);

  info->request  = r;
  info->sfn = sfn;

  info->s_conf = ap_get_module_config(r->server->module_config,  &lcgdm_ns_module);
  info->d_conf = ap_get_module_config(r->per_dir_config,         &lcgdm_ns_module);
  
  /* User info */
  if (user) {
    info->user = user;
  }
  else {
    if (!(info->user = dav_shared_get_user_credentials(r, info->ctx,
                                                       info->d_conf->anon_user,
                                                       info->d_conf->trusted_dns)))
      return dav_shared_new_error(r, NULL, HTTP_FORBIDDEN,
                                  "Can not authenticate the user");
  }

  /* Instantiate the catalog, if not in the connection notes */
  info->ctx = (dmlite_context*)apr_table_get(r->connection->notes, "dav_ns_ctx");
  if (info->ctx == NULL) {
    info->ctx = dmlite_context_new(info->s_conf->manager);
    if (info->ctx == NULL) {
      return dav_shared_new_error(r, NULL, HTTP_INTERNAL_SERVER_ERROR,
                                  "Could not instantiate a context: %s",
                                  dmlite_manager_error(info->s_conf->manager));
    }

    apr_pool_pre_cleanup_register(r->connection->pool, info->ctx,
                                  (apr_status_t(*)(void*))dmlite_context_free);
    
    apr_table_setn(r->connection->notes, "dav_ns_ctx", (char*)info->ctx);
    
    if (dmlite_setcredentials(info->ctx, info->user) != 0)
      return dav_shared_new_error(r, info->ctx, HTTP_FORBIDDEN,
                                  "Could not set credentials");
  }

  /* Extract parameters from the query */
  query = dav_shared_parse_query(r->pool, r->parsed_uri.query, &nargs);

#ifdef WITH_METALINK
  /* Explicit */
  info->metalink      = (apr_table_get(query, "metalink") != NULL);
  /* Through headers maybe? (i.e. aria2c) */
  if (!info->metalink && dav_shared_request_accepts(r, "application/metalink+xml")) {
    info->metalink = 1;
  }
#else
  info->metalink      = 0;
#endif
  info->space_token   = apr_table_get(query, "spacetoken");
  info->forbidden_str = apr_table_get(query, "forbidden");
  info->notfound_str  = apr_table_get(query, "notfound");
  if ((p = apr_table_get(query, "rid")))
    info->r_id = atol(p);
  else
    info->r_id = -1;

  /* Count in advance how many replicas */
  info->n_replicas = 0;
  snprintf(replica_key, sizeof(replica_key), "r%d", info->n_replicas + 1);
  while(apr_table_get(query, replica_key) != NULL) {
    ++info->n_replicas;
    snprintf(replica_key, sizeof(replica_key), "r%d", info->n_replicas + 1);
  }

  /* Allocate space */
  info->replicas     = apr_pcalloc(r->pool, sizeof(char*)   * info->n_replicas);
  info->replicas_ids = apr_pcalloc(r->pool, sizeof(int64_t) * info->n_replicas);

  /* Go through again :/ */
  for (i = 0; i < info->n_replicas; ++i) {
    const char *field_value;

    snprintf(replica_key, sizeof(replica_key), "r%d", i + 1);
    field_value = apr_table_get(query, replica_key);

    info->replicas[i] = apr_pcalloc(r->pool, sizeof(char) * PATH_MAX);

    if (sscanf(field_value, "%"PRId64",%s",
                            &info->replicas_ids[i], info->replicas[i]) != 2) {
      return dav_shared_new_error(r, NULL, HTTP_BAD_REQUEST, "Replica parameters malformed");
    }
  }

  /* Stat */
  switch (dmlite_statx(info->ctx, info->sfn, &(info->stat))) {
    /* We are good */
    case 0:
      exists = 1;
      break;
    /* Access denied */
    case DM_FORBIDDEN:
      /* If this is not a HEAD or a GET (both are M_GET), just fail,
       * but keep going otherwise */
      if (r->method_number != M_GET)
        return dav_shared_new_error(r, info->ctx, 0,
                                    "Access forbidden for %s on %s", info->sfn, r->method);
    case DM_NO_SUCH_FILE:
      exists = 0;
      /* When creating a file, break here */
      if (r->method_number == M_PUT || r->method_number == M_MKCOL ||
          r->method_number == M_MOVE)
        break;
      /* Now, fall-back to the next replica in the list, if any */
      info->redirect = dav_shared_build_aggregation_url(info->request->pool,
                                                        info->n_replicas,
                                                        (const char**)info->replicas,
                                                        info->replicas_ids,
                                                        info->forbidden_str,
                                                        info->notfound_str,
                                                        -1, info->r_id);
      if (info->redirect != NULL) {
        apr_table_set(r->headers_out, "Location", info->redirect);
        return dav_new_error(r->pool, HTTP_MOVED_TEMPORARILY, 0,
                             info->redirect);
      }
      /* We can't :(, so go to default */
    default:
      return dav_shared_new_error(r, info->ctx, 0, "Can not stat %s", info->sfn);
  }
  
  /* Create and return resource */
  *resource = apr_pcalloc(r->pool, sizeof(dav_resource));
  (*resource)->type   = DAV_RESOURCE_TYPE_REGULAR;
  (*resource)->exists = exists;
  (*resource)->collection = ((info->stat.stat.st_mode & S_IFDIR) != 0);
  (*resource)->uri    = sfn;
  (*resource)->info   = info;
  (*resource)->hooks  = &dav_ns_hooks_repository;
  (*resource)->pool   = r->pool;

  if (exists)
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                  "Resource for %s (%s) found (dir=%d)",
                  (*resource)->uri, (*resource)->info->sfn,
                  (*resource)->collection);
  else
    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                  "NULL resource for %s (%s) created",
                  (*resource)->uri, (*resource)->info->sfn);

  return NULL;
}