diff -r 65ac1342ba1f -r 3dfbd0b91950 src/server/daemon/resourcepool.c --- a/src/server/daemon/resourcepool.c Thu Jan 20 16:04:58 2022 +0100 +++ b/src/server/daemon/resourcepool.c Sat Jan 22 11:06:11 2022 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2020 Olaf Wintermann. All rights reserved. + * Copyright 2022 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,6 +29,100 @@ #include "resourcepool.h" #include "request.h" #include "session.h" +#include "../public/nsapi.h" + +#define RESOURCE_POOL_MAX_DEFAULT 32 + +#define RESOURCE_POOL_MAX_ALLOC 268435455 + +static UcxMap *resource_pool_types; + +int init_resource_pools(void) { + resource_pool_types = ucx_map_new(4); + return resource_pool_types ? 0 : 1; +} + + + +int resourcepool_new(ServerConfiguration *cfg, scstr_t type, scstr_t name, ConfigNode *node) { + ResourceType *restype = ucx_map_sstr_get(resource_pool_types, type); + if(!restype) { + log_ereport(LOG_MISCONFIG, "Unknown resource pool type: %s", type.ptr); + return 1; + } + + // convert ConfigNode to pblock + // no sub-objects allowed for this specific ConfigNode, therefore + // it can be represented as key-value-pairs + pblock *param = config_obj2pblock(cfg->pool, node); + if(!param) { + log_ereport(LOG_FAILURE, "resourcepool_new: OOM"); + return 1; + } + + ResourcePool *respool = pool_malloc(cfg->pool, sizeof(ResourcePool)); + if(!respool) { + log_ereport(LOG_FAILURE, "resourcepool_new: OOM"); + return 1; + } + respool->pool = cfg->pool; + + void *respool_data = restype->init(cfg->pool, param); + if(!respool_data) { + log_ereport(LOG_FAILURE, "Cannot create resource pool data: pool: %s type: %s", name.ptr, type.ptr); + return 1; + } + + respool->type = restype; + respool->data = respool_data; + respool->min = 0; // TODO: get from node + respool->max = RESOURCE_POOL_MAX_DEFAULT; // TODO: get from node + + // don't allow too large resource pools + // this prevents the need to check malloc integer overflows + if(respool->max > RESOURCE_POOL_MAX_ALLOC) { + respool->max = RESOURCE_POOL_MAX_ALLOC; + log_ereport(LOG_WARN, "Resource pool %s: limit max to %d", name.ptr, respool->max); + } + + respool->resalloc = respool->max; + respool->resources = pool_malloc(cfg->pool, respool->resalloc * sizeof(void*)); + + if(!respool->resources || ucx_map_sstr_put(cfg->resources, name, respool)) { + log_ereport(LOG_FAILURE, "Cannot add resource pool: OOM"); + // the only cleanup we have to do + restype->destroy(respool_data); + return 1; + } + + pthread_mutex_init(&respool->lock, NULL); + pthread_cond_init(&respool->available, NULL); + + if(resourcepool_create_resources(respool, respool->max)) { + log_ereport(LOG_FAILURE, "Resource pool %s: Cannot create resources", name.ptr); + resourcepool_destroy(respool); + return 1; + } + + return 0; +} + +int resourcepool_create_resources(ResourcePool *pool, int num_res) { + if(num_res > pool->resalloc) { + num_res = pool->resalloc; + } + + for(int i=pool->numresources;itype->createresource(pool->data); + if(resource) { + pool->resources[pool->numresources++] = resource; + } else { + return 1; // error + } + } + + return 0; +} ResourceData* resourcepool_lookup(Session *sn, Request *rq, const char *name, int flags) { NSAPIRequest *request = (NSAPIRequest*)rq; @@ -47,12 +141,21 @@ // TODO: get cached resource + /* ResourceType *type = ucx_map_cstr_get(cfg->resources, name); if(!type) { return NULL; } + */ + + + return NULL; } void resourcepool_free(ResourceData *data) { } + +void resourcepool_destroy(ResourcePool *respool) { + // TODO +}