src/server/daemon/resourcepool.c

branch
webdav
changeset 269
3dfbd0b91950
parent 260
4779a6fb4fbe
child 270
4cfaa02055cd
--- 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;i<num_res;i++) {
+        void *resource = pool->type->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
+}

mercurial