]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10167: Major updates to lifecycle management across a number of objects changing...
authorShane Bryldt <astaelan@gmail.com>
Thu, 20 Apr 2017 22:56:08 +0000 (16:56 -0600)
committerShane Bryldt <astaelan@gmail.com>
Thu, 20 Apr 2017 22:56:08 +0000 (16:56 -0600)
28 files changed:
libs/libblade/libblade.vcxproj
libs/libblade/libblade.vcxproj.filters
libs/libblade/src/blade.c
libs/libblade/src/blade_connection.c
libs/libblade/src/blade_identity.c
libs/libblade/src/blade_method.c
libs/libblade/src/blade_module.c
libs/libblade/src/blade_module_chat.c [deleted file]
libs/libblade/src/blade_module_wss.c
libs/libblade/src/blade_protocol.c
libs/libblade/src/blade_session.c
libs/libblade/src/blade_space.c
libs/libblade/src/blade_stack.c
libs/libblade/src/include/blade.h
libs/libblade/src/include/blade_method.h
libs/libblade/src/include/blade_module.h
libs/libblade/src/include/blade_module_wss.h [new file with mode: 0644]
libs/libblade/src/include/blade_protocol.h
libs/libblade/src/include/blade_space.h
libs/libblade/src/include/blade_stack.h
libs/libblade/src/include/blade_types.h
libs/libblade/src/include/ks_bencode.h
libs/libblade/src/ks_bencode.c
libs/libblade/test/bladec.c
libs/libblade/test/blades.c
libs/libks/src/include/ks_platform.h
libs/libks/src/ks_ssl.c
libs/libks/src/ks_thread_pool.c

index fcfe6d5d62c328ca04c291aeff83104b8f7fbf84..95562a7348081c1ab8dd75e81849780ff2d94d89 100644 (file)
     <ClCompile Include="src\blade_identity.c" />
     <ClCompile Include="src\blade_method.c" />
     <ClCompile Include="src\blade_module.c" />
-    <ClCompile Include="src\blade_module_chat.c" />
     <ClCompile Include="src\blade_module_wss.c" />
     <ClCompile Include="src\blade_protocol.c" />
     <ClCompile Include="src\blade_session.c" />
     <ClInclude Include="src\include\blade_identity.h" />
     <ClInclude Include="src\include\blade_method.h" />
     <ClInclude Include="src\include\blade_module.h" />
+    <ClInclude Include="src\include\blade_module_wss.h" />
     <ClInclude Include="src\include\blade_protocol.h" />
     <ClInclude Include="src\include\blade_session.h" />
     <ClInclude Include="src\include\blade_space.h" />
index dd3696e575ae0b00a1510a57fb9c78cad8d8f0f8..d25008d137f2f3a372125517482e74b83c996f0c 100644 (file)
@@ -36,9 +36,6 @@
     <ClCompile Include="src\blade_module.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="src\blade_module_chat.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="src\blade_module_wss.c">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClInclude Include="src\include\ks_dht-int.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="src\include\blade_module_wss.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
index af6671e396ce1dcdaa5f4aaa052e8f9088e10355..390a0f8bbbab67b405842df6a12c150def5d9c37 100644 (file)
@@ -40,7 +40,11 @@ KS_DECLARE(ks_status_t) blade_init(void)
 
 KS_DECLARE(ks_status_t) blade_shutdown(void)
 {
-       return ks_shutdown();
+       ks_status_t ret = ks_shutdown();
+#ifdef _WINDOWS_
+       _CrtDumpMemoryLeaks();
+#endif
+       return ret;
 }
 
 /* For Emacs:
index ec68cda64200524e92700a481951a2e16126ce56..3a71234c0efdc3c08b5216c4864da5cf30c8cfb3 100644 (file)
@@ -132,8 +132,6 @@ KS_DECLARE(ks_status_t) blade_connection_destroy(blade_connection_t **bcP)
        //ks_pool_free(bc->pool, bcP);
        ks_pool_close(&pool);
 
-       ks_log(KS_LOG_DEBUG, "Destroyed\n");
-
        *bcP = NULL;
 
        return KS_STATUS_SUCCESS;
index 5c2cecafad0443778b6bcc38dfa99caac5585268..c28c4a92f909298fb843d175a41be68ec99a1ce4 100644 (file)
@@ -45,6 +45,25 @@ struct blade_identity_s {
        ks_hash_t *parameters;
 };
 
+// @todo missed a structure to use cleanup callbacks
+static void blade_identity_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_identity_t *bi = (blade_identity_t *)ptr;
+
+       ks_assert(bi);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               if (bi->uri) ks_pool_free(bi->pool, &bi->uri);
+               if (bi->components) ks_pool_free(bi->pool, &bi->components);
+               if (bi->parameters) ks_hash_destroy(&bi->parameters);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
 
 KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool)
 {
@@ -55,6 +74,9 @@ KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t
 
        bi = ks_pool_alloc(pool, sizeof(blade_identity_t));
        bi->pool = pool;
+
+       ks_assert(ks_pool_set_cleanup(pool, bi, NULL, blade_identity_cleanup) == KS_STATUS_SUCCESS);
+
        *biP = bi;
 
        return KS_STATUS_SUCCESS;
index ac09c0d1096df7af74a69a0aed1ce2ea052b31de..9b38bb474d5805a097570b652c84941342f65b72 100644 (file)
@@ -44,6 +44,22 @@ struct blade_method_s {
        // @todo more fun descriptive information about the call for remote registrations
 };
 
+static void blade_method_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_method_t *bm = (blade_method_t *)ptr;
+
+       ks_assert(bm);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               ks_pool_free(bm->pool, &bm->name);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
 
 KS_DECLARE(ks_status_t) blade_method_create(blade_method_t **bmP, blade_space_t *bs, const char *name, blade_request_callback_t callback)
 {
@@ -58,35 +74,19 @@ KS_DECLARE(ks_status_t) blade_method_create(blade_method_t **bmP, blade_space_t
        bh = blade_space_handle_get(bs);
        ks_assert(bh);
 
-       pool = blade_handle_pool_get(bh);
+       pool = blade_space_pool_get(bs);
        ks_assert(pool);
 
        bm = ks_pool_alloc(pool, sizeof(blade_method_t));
        bm->handle = bh;
        bm->pool = pool;
        bm->space = bs;
-       bm->name = name; // @todo dup and keep copy? should mostly be literals
+       bm->name = ks_pstrdup(pool, name);
        bm->callback = callback;
 
-       *bmP = bm;
-
-    ks_log(KS_LOG_DEBUG, "Method Created: %s.%s\n", blade_space_path_get(bs), name);
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_method_destroy(blade_method_t **bmP)
-{
-       blade_method_t *bm = NULL;
+       ks_assert(ks_pool_set_cleanup(pool, bm, NULL, blade_method_cleanup) == KS_STATUS_SUCCESS);
 
-       ks_assert(bmP);
-       ks_assert(*bmP);
-
-       bm = *bmP;
-
-    ks_log(KS_LOG_DEBUG, "Method Destroyed: %s.%s\n", blade_space_path_get(bm->space), bm->name);
-
-       ks_pool_free(bm->pool, bmP);
+       *bmP = bm;
 
        return KS_STATUS_SUCCESS;
 }
index 2101420d44c2e723efcae287f0a81edc69e85a5f..0737e0d871f034d1babc1f066a5e4e5b9675f2c4 100644 (file)
@@ -36,6 +36,7 @@
 struct blade_module_s {
        blade_handle_t *handle;
        ks_pool_t *pool;
+       const char *id;
 
        void *module_data;
        blade_module_callbacks_t *module_callbacks;
@@ -60,6 +61,7 @@ static void blade_module_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_
 KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t *bh, ks_pool_t *pool, void *module_data, blade_module_callbacks_t *module_callbacks)
 {
        blade_module_t *bm = NULL;
+       uuid_t uuid;
 
        ks_assert(bmP);
        ks_assert(bh);
@@ -67,9 +69,12 @@ KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t
        ks_assert(module_data);
        ks_assert(module_callbacks);
 
+       ks_uuid(&uuid);
+
        bm = ks_pool_alloc(pool, sizeof(blade_module_t));
        bm->handle = bh;
        bm->pool = pool;
+       bm->id = ks_uuid_str(pool, &uuid);
        bm->module_data = module_data;
        bm->module_callbacks = module_callbacks;
 
@@ -82,6 +87,25 @@ KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t
        return KS_STATUS_SUCCESS;
 }
 
+KS_DECLARE(ks_status_t) blade_module_destroy(blade_module_t **bmP)
+{
+       blade_module_t *bm = NULL;
+       ks_pool_t *pool = NULL;
+
+       ks_assert(bmP);
+       ks_assert(*bmP);
+
+       bm = *bmP;
+
+       pool = bm->pool;
+       //ks_pool_free(bm->pool, bmP);
+       ks_pool_close(&pool);
+
+       *bmP = NULL;
+
+       return KS_STATUS_SUCCESS;
+}
+
 KS_DECLARE(blade_handle_t *) blade_module_handle_get(blade_module_t *bm)
 {
        ks_assert(bm);
@@ -89,6 +113,20 @@ KS_DECLARE(blade_handle_t *) blade_module_handle_get(blade_module_t *bm)
        return bm->handle;
 }
 
+KS_DECLARE(ks_pool_t *) blade_module_pool_get(blade_module_t *bm)
+{
+       ks_assert(bm);
+
+       return bm->pool;
+}
+
+KS_DECLARE(const char *) blade_module_id_get(blade_module_t *bm)
+{
+       ks_assert(bm);
+
+       return bm->id;
+}
+
 KS_DECLARE(void *) blade_module_data_get(blade_module_t *bm)
 {
        ks_assert(bm);
@@ -96,6 +134,12 @@ KS_DECLARE(void *) blade_module_data_get(blade_module_t *bm)
        return bm->module_data;
 }
 
+KS_DECLARE(blade_module_callbacks_t *) blade_module_callbacks_get(blade_module_t *bm)
+{
+       ks_assert(bm);
+
+       return bm->module_callbacks;
+}
 
 /* For Emacs:
  * Local Variables:
diff --git a/libs/libblade/src/blade_module_chat.c b/libs/libblade/src/blade_module_chat.c
deleted file mode 100644 (file)
index ea5579d..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (c) 2017, Shane Bryldt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "blade.h"
-
-typedef struct blade_module_chat_s blade_module_chat_t;
-
-struct blade_module_chat_s {
-       blade_handle_t *handle;
-       ks_pool_t *pool;
-       ks_thread_pool_t *tpool;
-       blade_module_t *module;
-       blade_module_callbacks_t *module_callbacks;
-
-       const char *session_state_callback_id;
-       ks_list_t *participants;
-};
-
-
-ks_status_t blade_module_chat_create(blade_module_chat_t **bm_chatP, blade_handle_t *bh);
-ks_status_t blade_module_chat_destroy(blade_module_chat_t **bm_chatP);
-
-// @todo remove exporting this, it's only temporary until DSO loading is in place so wss module can be loaded
-KS_DECLARE(ks_status_t) blade_module_chat_on_load(blade_module_t **bmP, blade_handle_t *bh);
-KS_DECLARE(ks_status_t) blade_module_chat_on_unload(blade_module_t *bm);
-KS_DECLARE(ks_status_t) blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config);
-KS_DECLARE(ks_status_t) blade_module_chat_on_shutdown(blade_module_t *bm);
-
-void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
-
-ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq);
-ks_bool_t blade_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq);
-ks_bool_t blade_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq);
-
-static blade_module_callbacks_t g_module_chat_callbacks =
-{
-       blade_module_chat_on_load,
-       blade_module_chat_on_unload,
-       blade_module_chat_on_startup,
-       blade_module_chat_on_shutdown,
-};
-
-
-static void blade_module_chat_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
-{
-       blade_module_chat_t *bm_chat = (blade_module_chat_t *)ptr;
-
-       ks_assert(bm_chat);
-
-       switch (action) {
-       case KS_MPCL_ANNOUNCE:
-               break;
-       case KS_MPCL_TEARDOWN:
-               //ks_list_destroy(&bm_chat->participants);
-               blade_module_chat_on_shutdown(bm_chat->module);
-               break;
-       case KS_MPCL_DESTROY:
-               break;
-       }
-}
-
-
-ks_status_t blade_module_chat_create(blade_module_chat_t **bm_chatP, blade_handle_t *bh)
-{
-       blade_module_chat_t *bm_chat = NULL;
-       ks_pool_t *pool = NULL;
-
-       ks_assert(bm_chatP);
-       ks_assert(bh);
-
-       ks_pool_open(&pool);
-       ks_assert(pool);
-
-    bm_chat = ks_pool_alloc(pool, sizeof(blade_module_chat_t));
-       bm_chat->handle = bh;
-       bm_chat->pool = pool;
-       bm_chat->tpool = blade_handle_tpool_get(bh);
-       bm_chat->session_state_callback_id = NULL;
-
-       ks_list_create(&bm_chat->participants, pool);
-       ks_assert(bm_chat->participants);
-
-       blade_module_create(&bm_chat->module, bh, pool, bm_chat, &g_module_chat_callbacks);
-       bm_chat->module_callbacks = &g_module_chat_callbacks;
-
-       ks_assert(ks_pool_set_cleanup(pool, bm_chat, NULL, blade_module_chat_cleanup) == KS_STATUS_SUCCESS);
-
-       ks_log(KS_LOG_DEBUG, "Created\n");
-
-       *bm_chatP = bm_chat;
-
-       return KS_STATUS_SUCCESS;
-}
-
-ks_status_t blade_module_chat_destroy(blade_module_chat_t **bm_chatP)
-{
-       blade_module_chat_t *bm_chat = NULL;
-       ks_pool_t *pool = NULL;
-
-       ks_assert(bm_chatP);
-       ks_assert(*bm_chatP);
-
-       bm_chat = *bm_chatP;
-
-       pool = bm_chat->pool;
-       //ks_pool_free(bm_chat->pool, bm_chatP);
-       ks_pool_close(&pool);
-
-       ks_log(KS_LOG_DEBUG, "Destroyed\n");
-
-       *bm_chatP = NULL;
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_module_chat_on_load(blade_module_t **bmP, blade_handle_t *bh)
-{
-       blade_module_chat_t *bm_chat = NULL;
-
-       ks_assert(bmP);
-       ks_assert(bh);
-
-       blade_module_chat_create(&bm_chat, bh);
-       ks_assert(bm_chat);
-
-       *bmP = bm_chat->module;
-
-       ks_log(KS_LOG_DEBUG, "Loaded\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_module_chat_on_unload(blade_module_t *bm)
-{
-       blade_module_chat_t *bm_chat = NULL;
-
-       ks_assert(bm);
-
-       bm_chat = blade_module_data_get(bm);
-
-       blade_module_chat_destroy(&bm_chat);
-
-       ks_log(KS_LOG_DEBUG, "Unloaded\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-ks_status_t blade_module_chat_config(blade_module_chat_t *bm_chat, config_setting_t *config)
-{
-       config_setting_t *chat = NULL;
-
-       ks_assert(bm_chat);
-       ks_assert(config);
-
-       if (!config_setting_is_group(config)) {
-               ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
-               return KS_STATUS_FAIL;
-       }
-
-       chat = config_setting_get_member(config, "chat");
-       if (chat) {
-       }
-
-
-       // Configuration is valid, now assign it to the variables that are used
-       // If the configuration was invalid, then this does not get changed
-
-       ks_log(KS_LOG_DEBUG, "Configured\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config)
-{
-       blade_module_chat_t *bm_chat = NULL;
-       blade_space_t *space = NULL;
-       blade_method_t *method = NULL;
-
-       ks_assert(bm);
-       ks_assert(config);
-
-       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
-
-    if (blade_module_chat_config(bm_chat, config) != KS_STATUS_SUCCESS) {
-               ks_log(KS_LOG_DEBUG, "blade_module_chat_config failed\n");
-               return KS_STATUS_FAIL;
-       }
-
-       blade_space_create(&space, bm_chat->handle, bm, "blade.chat");
-       ks_assert(space);
-
-       blade_method_create(&method, space, "join", blade_chat_join_request_handler);
-       ks_assert(method);
-       blade_space_methods_add(space, method);
-
-       blade_method_create(&method, space, "leave", blade_chat_leave_request_handler);
-       ks_assert(method);
-       blade_space_methods_add(space, method);
-
-       blade_method_create(&method, space, "send", blade_chat_send_request_handler);
-       ks_assert(method);
-       blade_space_methods_add(space, method);
-
-       blade_handle_space_register(space);
-
-       blade_handle_session_state_callback_register(blade_module_handle_get(bm), bm, blade_module_chat_on_session_state, &bm_chat->session_state_callback_id);
-
-       ks_log(KS_LOG_DEBUG, "Started\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_module_chat_on_shutdown(blade_module_t *bm)
-{
-       blade_module_chat_t *bm_chat = NULL;
-
-       ks_assert(bm);
-
-       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
-       ks_assert(bm_chat);
-
-       if (bm_chat->session_state_callback_id) blade_handle_session_state_callback_unregister(blade_module_handle_get(bm), bm_chat->session_state_callback_id);
-       bm_chat->session_state_callback_id = NULL;
-
-       ks_log(KS_LOG_DEBUG, "Stopped\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data)
-{
-       blade_module_t *bm = NULL;
-       blade_module_chat_t *bm_chat = NULL;
-
-       ks_assert(bs);
-       ks_assert(data);
-
-       bm = (blade_module_t *)data;
-       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
-       ks_assert(bm_chat);
-
-       if (blade_session_state_get(bs) == BLADE_SESSION_STATE_HANGUP && condition == BLADE_SESSION_STATE_CONDITION_PRE) {
-               cJSON *props = NULL;
-
-               ks_log(KS_LOG_DEBUG, "Removing session from chat participants if present\n");
-
-               props = blade_session_properties_get(bs);
-               ks_assert(props);
-
-               cJSON_DeleteItemFromObject(props, "blade.chat.participant");
-
-               ks_list_delete(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
-       }
-}
-
-ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq)
-{
-       blade_module_chat_t *bm_chat = NULL;
-       blade_session_t *bs = NULL;
-       cJSON *res = NULL;
-       cJSON *props = NULL;
-       cJSON *props_participant = NULL;
-
-       ks_assert(bm);
-       ks_assert(breq);
-
-       ks_log(KS_LOG_DEBUG, "Request Received!\n");
-
-       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
-       ks_assert(bm_chat);
-
-       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
-       ks_assert(bs);
-
-       // @todo properties only used to demonstrate a flexible container for session data, should just rely on the participants list/hash
-       blade_session_properties_write_lock(bs, KS_TRUE);
-
-       props = blade_session_properties_get(bs);
-       ks_assert(props);
-
-       props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
-       if (props_participant && props_participant->type == cJSON_True) {
-               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to join chat but is already a participant\n", blade_session_id_get(bs));
-               blade_rpc_error_create(&res, NULL, breq->message_id, -10000, "Already a participant of chat");
-       } else {
-               ks_log(KS_LOG_DEBUG, "Session (%s) joined chat\n", blade_session_id_get(bs));
-
-               if (props_participant) props_participant->type = cJSON_True;
-               else cJSON_AddTrueToObject(props, "blade.chat.participant");
-
-               ks_list_append(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and cleanup when removed
-
-               blade_rpc_response_create(&res, NULL, breq->message_id);
-
-               // @todo create an event to send to participants when a session joins and leaves, send after main response though
-       }
-
-       blade_session_properties_write_unlock(bs);
-
-       blade_session_send(bs, res, NULL);
-
-       blade_session_read_unlock(bs);
-
-       cJSON_Delete(res);
-
-       return KS_FALSE;
-}
-
-ks_bool_t blade_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq)
-{
-       blade_module_chat_t *bm_chat = NULL;
-       blade_session_t *bs = NULL;
-       cJSON *res = NULL;
-       cJSON *props = NULL;
-       cJSON *props_participant = NULL;
-
-       ks_assert(bm);
-       ks_assert(breq);
-
-       ks_log(KS_LOG_DEBUG, "Request Received!\n");
-
-       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
-       ks_assert(bm_chat);
-
-       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
-       ks_assert(bs);
-
-       blade_session_properties_write_lock(bs, KS_TRUE);
-
-       props = blade_session_properties_get(bs);
-       ks_assert(props);
-
-       props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
-       if (!props_participant || props_participant->type == cJSON_False) {
-               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to leave chat but is not a participant\n", blade_session_id_get(bs));
-               blade_rpc_error_create(&res, NULL, breq->message_id, -10000, "Not a participant of chat");
-       } else {
-               ks_log(KS_LOG_DEBUG, "Session (%s) left chat\n", blade_session_id_get(bs));
-
-               cJSON_DeleteItemFromObject(props, "blade.chat.participant");
-
-               ks_list_delete(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
-
-               blade_rpc_response_create(&res, NULL, breq->message_id);
-
-               // @todo create an event to send to participants when a session joins and leaves, send after main response though
-       }
-
-       blade_session_properties_write_unlock(bs);
-
-       blade_session_send(bs, res, NULL);
-
-       blade_session_read_unlock(bs);
-
-       cJSON_Delete(res);
-
-       return KS_FALSE;
-}
-
-ks_bool_t blade_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq)
-{
-       blade_module_chat_t *bm_chat = NULL;
-       blade_session_t *bs = NULL;
-       cJSON *params = NULL;
-       cJSON *res = NULL;
-       cJSON *event = NULL;
-       const char *message = NULL;
-       ks_bool_t sendevent = KS_FALSE;
-
-       ks_assert(bm);
-       ks_assert(breq);
-
-       ks_log(KS_LOG_DEBUG, "Request Received!\n");
-
-       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
-       ks_assert(bm_chat);
-
-       params = cJSON_GetObjectItem(breq->message, "params"); // @todo cache this in blade_request_t for quicker/easier access
-       if (!params) {
-               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to send chat message with no 'params' object\n", blade_session_id_get(bs));
-               blade_rpc_error_create(&res, NULL, breq->message_id, -32602, "Missing params object");
-       } else if (!(message = cJSON_GetObjectCstr(params, "message"))) {
-               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to send chat message with no 'message'\n", blade_session_id_get(bs));
-               blade_rpc_error_create(&res, NULL, breq->message_id, -32602, "Missing params message string");
-       }
-
-       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
-       ks_assert(bs);
-
-       if (!res) {
-               blade_rpc_response_create(&res, NULL, breq->message_id);
-               sendevent = KS_TRUE;
-       }
-       blade_session_send(bs, res, NULL);
-
-       blade_session_read_unlock(bs);
-
-       cJSON_Delete(res);
-
-       if (sendevent) {
-               blade_rpc_event_create(&event, &res, "blade.chat.message");
-               ks_assert(event);
-               cJSON_AddStringToObject(res, "from", breq->session_id); // @todo should really be the identity, but we don't have that in place yet
-               cJSON_AddStringToObject(res, "message", message);
-
-               blade_handle_sessions_send(breq->handle, bm_chat->participants, NULL, event);
-
-               cJSON_Delete(event);
-       }
-
-       return KS_FALSE;
-}
-
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
- */
index e23dd9aa561c5a9309ea6b5e9245f2d122ebbda8..d4ab63fe76c61da1139c0026760ccc413243e1df 100644 (file)
@@ -69,20 +69,10 @@ struct blade_transport_wss_s {
 
 
 
-ks_status_t blade_module_wss_create(blade_module_wss_t **bm_wssP, blade_handle_t *bh);
-ks_status_t blade_module_wss_destroy(blade_module_wss_t **bm_wssP);
-
-// @todo remove exporting this, it's only temporary until DSO loading is in place so wss module can be loaded
-KS_DECLARE(ks_status_t) blade_module_wss_on_load(blade_module_t **bmP, blade_handle_t *bh);
-KS_DECLARE(ks_status_t) blade_module_wss_on_unload(blade_module_t *bm);
-KS_DECLARE(ks_status_t) blade_module_wss_on_startup(blade_module_t *bm, config_setting_t *config);
-KS_DECLARE(ks_status_t) blade_module_wss_on_shutdown(blade_module_t *bm);
-
 ks_status_t blade_module_wss_listen(blade_module_wss_t *bm, ks_sockaddr_t *addr);
 void *blade_module_wss_listeners_thread(ks_thread_t *thread, void *data);
 
 
-
 ks_status_t blade_transport_wss_create(blade_transport_wss_t **bt_wssP, ks_pool_t *pool, blade_module_wss_t *bm_wss, ks_socket_t sock, const char *session_id);
 
 ks_status_t blade_transport_wss_on_connect(blade_connection_t **bcP, blade_module_t *bm, blade_identity_t *target, const char *session_id);
@@ -107,8 +97,6 @@ blade_connection_state_hook_t blade_transport_wss_on_state_ready_outbound(blade_
 
 static blade_module_callbacks_t g_module_wss_callbacks =
 {
-       blade_module_wss_on_load,
-       blade_module_wss_on_unload,
        blade_module_wss_on_startup,
        blade_module_wss_on_shutdown,
 };
@@ -145,19 +133,18 @@ static void blade_module_wss_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_p
        case KS_MPCL_ANNOUNCE:
                break;
        case KS_MPCL_TEARDOWN:
-               blade_module_wss_on_shutdown(bm_wss->module);
                break;
        case KS_MPCL_DESTROY:
                break;
        }
 }
 
-ks_status_t blade_module_wss_create(blade_module_wss_t **bm_wssP, blade_handle_t *bh)
+KS_DECLARE(ks_status_t) blade_module_wss_create(blade_module_t **bmP, blade_handle_t *bh)
 {
        blade_module_wss_t *bm_wss = NULL;
        ks_pool_t *pool = NULL;
 
-       ks_assert(bm_wssP);
+       ks_assert(bmP);
        ks_assert(bh);
 
        ks_pool_open(&pool);
@@ -175,63 +162,11 @@ ks_status_t blade_module_wss_create(blade_module_wss_t **bm_wssP, blade_handle_t
 
        ks_log(KS_LOG_DEBUG, "Created\n");
 
-       *bm_wssP = bm_wss;
-
-       return KS_STATUS_SUCCESS;
-}
-
-ks_status_t blade_module_wss_destroy(blade_module_wss_t **bm_wssP)
-{
-       blade_module_wss_t *bm_wss = NULL;
-       ks_pool_t *pool = NULL;
-
-       ks_assert(bm_wssP);
-       ks_assert(*bm_wssP);
-
-       bm_wss = *bm_wssP;
-
-       pool = bm_wss->pool;
-       //ks_pool_free(bm_wss->pool, bm_wssP);
-       ks_pool_close(&pool);
-
-       ks_log(KS_LOG_DEBUG, "Destroyed\n");
-
-       *bm_wssP = NULL;
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_module_wss_on_load(blade_module_t **bmP, blade_handle_t *bh)
-{
-       blade_module_wss_t *bm_wss = NULL;
-
-       ks_assert(bmP);
-       ks_assert(bh);
-
-       blade_module_wss_create(&bm_wss, bh);
-       ks_assert(bm_wss);
-
        *bmP = bm_wss->module;
 
-       ks_log(KS_LOG_DEBUG, "Loaded\n");
-
        return KS_STATUS_SUCCESS;
 }
 
-KS_DECLARE(ks_status_t) blade_module_wss_on_unload(blade_module_t *bm)
-{
-       blade_module_wss_t *bm_wss = NULL;
-
-       ks_assert(bm);
-
-       bm_wss = blade_module_data_get(bm);
-
-       blade_module_wss_destroy(&bm_wss);
-
-       ks_log(KS_LOG_DEBUG, "Unloaded\n");
-
-       return KS_STATUS_SUCCESS;
-}
 
 ks_status_t blade_module_wss_config(blade_module_wss_t *bm_wss, config_setting_t *config)
 {
index 191d485d51a6d080850c36a513a68618a38ca4b0..78a686d4e925ccc5f1e66a36748aad2627430115 100644 (file)
 
 #include "blade.h"
 
+static void blade_request_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_request_t *breq = (blade_request_t *)ptr;
+
+       ks_assert(breq);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               ks_pool_free(breq->pool, (void **)&breq->session_id);
+               cJSON_Delete(breq->message);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
+
 KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP,
                                                                                         blade_handle_t *bh,
+                                                                                        ks_pool_t *pool,
                                                                                         const char *session_id,
                                                                                         cJSON *json,
                                                                                         blade_response_callback_t callback)
 {
        blade_request_t *breq = NULL;
-       ks_pool_t *pool = NULL;
 
        ks_assert(breqP);
        ks_assert(bh);
+       ks_assert(pool);
        ks_assert(session_id);
        ks_assert(json);
 
-       pool = blade_handle_pool_get(bh);
-       ks_assert(pool);
-
        breq = ks_pool_alloc(pool, sizeof(blade_request_t));
        breq->handle = bh;
        breq->pool = pool;
@@ -58,6 +74,8 @@ KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP,
        breq->message_id = cJSON_GetObjectCstr(breq->message, "id");
        breq->callback = callback;
 
+       ks_assert(ks_pool_set_cleanup(pool, breq, NULL, blade_request_cleanup) == KS_STATUS_SUCCESS);
+
        *breqP = breq;
 
        return KS_STATUS_SUCCESS;
@@ -72,33 +90,46 @@ KS_DECLARE(ks_status_t) blade_request_destroy(blade_request_t **breqP)
 
        breq = *breqP;
 
-       ks_pool_free(breq->pool, (void **)&breq->session_id);
-       cJSON_Delete(breq->message);
-
        ks_pool_free(breq->pool, breqP);
 
        return KS_STATUS_SUCCESS;
 }
 
+static void blade_response_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_response_t *bres = (blade_response_t *)ptr;
+
+       ks_assert(bres);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               ks_pool_free(bres->pool, (void **)&bres->session_id);
+               blade_request_destroy(&bres->request);
+               cJSON_Delete(bres->message);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
 
 KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP,
                                                                                          blade_handle_t *bh,
+                                                                                         ks_pool_t *pool,
                                                                                          const char *session_id,
                                                                                          blade_request_t *breq,
                                                                                          cJSON *json)
 {
        blade_response_t *bres = NULL;
-       ks_pool_t *pool = NULL;
 
        ks_assert(bresP);
        ks_assert(bh);
+       ks_assert(pool);
        ks_assert(session_id);
        ks_assert(breq);
        ks_assert(json);
 
-       pool = blade_handle_pool_get(bh);
-       ks_assert(pool);
-
        bres = ks_pool_alloc(pool, sizeof(blade_response_t));
        bres->handle = bh;
        bres->pool = pool;
@@ -106,6 +137,8 @@ KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP,
        bres->request = breq;
        bres->message = cJSON_Duplicate(json, 1);
 
+       ks_assert(ks_pool_set_cleanup(pool, bres, NULL, blade_response_cleanup) == KS_STATUS_SUCCESS);
+
        *bresP = bres;
 
        return KS_STATUS_SUCCESS;
@@ -120,37 +153,51 @@ KS_DECLARE(ks_status_t) blade_response_destroy(blade_response_t **bresP)
 
        bres = *bresP;
 
-       ks_pool_free(bres->pool, (void **)&bres->session_id);
-       blade_request_destroy(&bres->request);
-       cJSON_Delete(bres->message);
-
        ks_pool_free(bres->pool, bresP);
 
        return KS_STATUS_SUCCESS;
 }
 
+static void blade_event_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_event_t *bev = (blade_event_t *)ptr;
+
+       ks_assert(bev);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               ks_pool_free(bev->pool, &bev->session_id);
+               cJSON_Delete(bev->message);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
+
 KS_DECLARE(ks_status_t) blade_event_create(blade_event_t **bevP,
                                                                                   blade_handle_t *bh,
+                                                                                  ks_pool_t *pool,
                                                                                   const char *session_id,
                                                                                   cJSON *json)
 {
        blade_event_t *bev = NULL;
-       ks_pool_t *pool = NULL;
 
        ks_assert(bevP);
        ks_assert(bh);
+       ks_assert(pool);
        ks_assert(session_id);
        ks_assert(json);
 
-       pool = blade_handle_pool_get(bh);
-       ks_assert(pool);
-
        bev = ks_pool_alloc(pool, sizeof(blade_event_t));
        bev->handle = bh;
        bev->pool = pool;
        bev->session_id = ks_pstrdup(pool, session_id);
        bev->message = cJSON_Duplicate(json, 1);
 
+       ks_assert(ks_pool_set_cleanup(pool, bev, NULL, blade_event_cleanup) == KS_STATUS_SUCCESS);
+
        *bevP = bev;
 
        return KS_STATUS_SUCCESS;
@@ -165,14 +212,12 @@ KS_DECLARE(ks_status_t) blade_event_destroy(blade_event_t **bevP)
 
        bev = *bevP;
 
-       ks_pool_free(bev->pool, (void **)&bev->session_id);
-       cJSON_Delete(bev->message);
-
        ks_pool_free(bev->pool, bevP);
 
        return KS_STATUS_SUCCESS;
 }
 
+
 KS_DECLARE(ks_status_t) blade_rpc_request_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method)
 {
        cJSON *root = NULL;
index a2412613eca92bf05ec9914430f16f9894ad692c..667687d68b1d3b95068981fb112bc4d537c01bb2 100644 (file)
@@ -163,8 +163,6 @@ KS_DECLARE(ks_status_t) blade_session_destroy(blade_session_t **bsP)
        //ks_pool_free(bs->pool, bsP);
        ks_pool_close(&pool);
 
-       ks_log(KS_LOG_DEBUG, "Destroyed\n");
-
        *bsP = NULL;
 
        return KS_STATUS_SUCCESS;
@@ -617,7 +615,7 @@ KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, bla
                // 1) Sending a request (client: method caller or consumer)
                ks_log(KS_LOG_DEBUG, "Session (%s) sending request (%s) for %s\n", bs->id, id, method);
 
-               blade_request_create(&request, bs->handle, bs->id, json, callback);
+               blade_request_create(&request, bs->handle, blade_handle_pool_get(bs->handle), bs->id, json, callback);
                ks_assert(request);
 
                // @todo set request TTL and figure out when requests are checked for expiration (separate thread in the handle?)
@@ -681,7 +679,7 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
                } else {
                        ks_log(KS_LOG_DEBUG, "Session (%s) processing event %s\n", bs->id, blade_event);
 
-                       blade_event_create(&bev, bs->handle, bs->id, json);
+                       blade_event_create(&bev, bs->handle, bs->pool, bs->id, json);
                        ks_assert(bev);
 
                        disconnect = callback(bev);
@@ -736,7 +734,7 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
                        callback = blade_method_callback_get(tmp_method);
                        ks_assert(callback);
 
-                       blade_request_create(&breq, bs->handle, bs->id, json, NULL);
+                       blade_request_create(&breq, bs->handle, blade_handle_pool_get(bs->handle), bs->id, json, NULL);
                        ks_assert(breq);
 
                        disconnect = callback(blade_space_module_get(tmp_space), breq);
@@ -755,7 +753,7 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
                        }
                        blade_handle_requests_remove(breq);
 
-                       blade_response_create(&bres, bs->handle, bs->id, breq, json);
+                       blade_response_create(&bres, bs->handle, bs->pool, bs->id, breq, json);
                        ks_assert(bres);
 
                        disconnect = breq->callback(bres);
index 33931c2453cb3d32fada2befc76c14f2c4456470..29682d61ae0d634abb229d1826a086694423f65a 100644 (file)
@@ -42,6 +42,23 @@ struct blade_space_s {
        ks_hash_t *methods;
 };
 
+static void blade_space_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_space_t *bs = (blade_space_t *)ptr;
+
+       ks_assert(bs);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               ks_pool_free(bs->pool, &bs->path);
+               ks_hash_destroy(&bs->methods);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
 
 KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, blade_module_t *bm, const char *path)
 {
@@ -52,16 +69,19 @@ KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *
        ks_assert(bh);
        ks_assert(path);
 
-       pool = blade_handle_pool_get(bh);
+       pool = blade_module_pool_get(bm);
+       ks_assert(pool);
 
        bs = ks_pool_alloc(pool, sizeof(blade_space_t));
        bs->handle = bh;
        bs->pool = pool;
        bs->module = bm;
-       bs->path = path; // @todo dup and keep copy? should mostly be literals
-       ks_hash_create(&bs->methods, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, bs->pool);
+       bs->path = ks_pstrdup(pool, path);
+       ks_hash_create(&bs->methods, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_VALUE, bs->pool);
        ks_assert(bs);
 
+       ks_assert(ks_pool_set_cleanup(pool, bs, NULL, blade_space_cleanup) == KS_STATUS_SUCCESS);
+
        *bsP = bs;
 
        ks_log(KS_LOG_DEBUG, "Space Created: %s\n", path);
@@ -69,38 +89,18 @@ KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *
        return KS_STATUS_SUCCESS;
 }
 
-KS_DECLARE(ks_status_t) blade_space_destroy(blade_space_t **bsP)
+KS_DECLARE(blade_handle_t *) blade_space_handle_get(blade_space_t *bs)
 {
-       blade_space_t *bs = NULL;
-       ks_hash_iterator_t *it = NULL;
-
-       ks_assert(bsP);
-       ks_assert(*bsP);
-
-       bs = *bsP;
-
-       for (it = ks_hash_first(bs->methods, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
-        void *key = NULL;
-               blade_method_t *value = NULL;
-
-               ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
-               blade_method_destroy(&value);
-       }
-
-       ks_hash_destroy(&bs->methods);
-
-       ks_log(KS_LOG_DEBUG, "Space Destroyed: %s\n", bs->path);
-
-       ks_pool_free(bs->pool, bsP);
+       ks_assert(bs);
 
-       return KS_STATUS_SUCCESS;
+       return bs->handle;
 }
 
-KS_DECLARE(blade_handle_t *) blade_space_handle_get(blade_space_t *bs)
+KS_DECLARE(ks_pool_t *) blade_space_pool_get(blade_space_t *bs)
 {
        ks_assert(bs);
 
-       return bs->handle;
+       return bs->pool;
 }
 
 KS_DECLARE(blade_module_t *) blade_space_module_get(blade_space_t *bs)
@@ -119,9 +119,7 @@ KS_DECLARE(const char *) blade_space_path_get(blade_space_t *bs)
 
 KS_DECLARE(ks_status_t) blade_space_methods_add(blade_space_t *bs, blade_method_t *bm)
 {
-       ks_status_t ret = KS_STATUS_SUCCESS;
        const char *name = NULL;
-       blade_method_t *bm_old = NULL;
 
        ks_assert(bs);
        ks_assert(bm);
@@ -129,20 +127,13 @@ KS_DECLARE(ks_status_t) blade_space_methods_add(blade_space_t *bs, blade_method_
        name = blade_method_name_get(bm);
        ks_assert(name);
 
-       ks_hash_write_lock(bs->methods);
-       bm_old = ks_hash_search(bs->methods, (void *)name, KS_UNLOCKED);
-       if (bm_old) ks_hash_remove(bs->methods, (void *)name);
-       ret = ks_hash_insert(bs->methods, (void *)name, (void *)bm);
-       ks_hash_write_unlock(bs->methods);
-
-       if (bm_old) blade_method_destroy(&bm_old);
+       ks_hash_insert(bs->methods, (void *)name, (void *)bm);
 
-       return ret;
+       return KS_STATUS_SUCCESS;
 }
 
 KS_DECLARE(ks_status_t) blade_space_methods_remove(blade_space_t *bs, blade_method_t *bm)
 {
-       ks_status_t ret = KS_STATUS_SUCCESS;
        const char *name = NULL;
 
        ks_assert(bs);
@@ -151,22 +142,18 @@ KS_DECLARE(ks_status_t) blade_space_methods_remove(blade_space_t *bs, blade_meth
        name = blade_method_name_get(bm);
        ks_assert(name);
 
-       ks_hash_write_lock(bs->methods);
        ks_hash_remove(bs->methods, (void *)name);
-       ks_hash_write_unlock(bs->methods);
 
-       return ret;
+       return KS_STATUS_SUCCESS;
 }
 
 KS_DECLARE(blade_method_t *) blade_space_methods_get(blade_space_t *bs, const char *name)
 {
        blade_method_t *bm = NULL;
-
        ks_assert(bs);
        ks_assert(name);
 
-       ks_hash_read_lock(bs->methods);
-       bm = ks_hash_search(bs->methods, (void *)name, KS_UNLOCKED);
+       bm = ks_hash_search(bs->methods, (void *)name, KS_READLOCKED);
        ks_hash_read_unlock(bs->methods);
 
        return bm;
index feef6f6adca8681fe74aabcaeab7a467175c9bef..2111157da8f0b4c5754e29b9d5468cbf69a0dc45 100644 (file)
@@ -35,8 +35,6 @@
 
 typedef enum {
        BH_NONE = 0,
-       BH_MYPOOL = (1 << 0),
-       BH_MYTPOOL = (1 << 1)
 } bhpvt_flag_t;
 
 struct blade_handle_s {
@@ -44,27 +42,24 @@ struct blade_handle_s {
        ks_pool_t *pool;
        ks_thread_pool_t *tpool;
 
-       config_setting_t *config_directory;
-       config_setting_t *config_datastore;
-
+       ks_hash_t *modules; // registered modules
        ks_hash_t *transports; // registered transports exposed by modules, NOT active connections
        ks_hash_t *spaces; // registered method spaces exposed by modules
+
        // registered event callback registry
        // @todo should probably use a blade_handle_event_registration_t and contain optional userdata to pass from registration back into the callback, like
-       // a blade_module_t to get at inner module data for events that service modules may need to subscribe to between each other
+       // a blade_module_t to get at inner module data for events that service modules may need to subscribe to between each other, but this may evolve into
+       // an implementation based on ESL
        ks_hash_t *events;
 
        //blade_identity_t *identity;
        blade_datastore_t *datastore;
 
-       // @todo insert on connection creations, remove on connection destructions, key based on a UUID for the connection
        ks_hash_t *connections; // active connections keyed by connection id
 
-       // @todo insert on session creations, remove on session destructions, key based on a UUID for the session
        ks_hash_t *sessions; // active sessions keyed by session id
        ks_hash_t *session_state_callbacks;
 
-       // @todo another hash with sessions keyed by the remote identity without parameters for quick lookup by target identity on sending?
        ks_hash_t *requests; // outgoing requests waiting for a response keyed by the message id
 };
 
@@ -76,6 +71,23 @@ struct blade_handle_transport_registration_s {
        blade_transport_callbacks_t *callbacks;
 };
 
+
+static void blade_handle_transport_registration_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_handle_transport_registration_t *bhtr = (blade_handle_transport_registration_t *)ptr;
+
+       ks_assert(bhtr);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
+
 KS_DECLARE(ks_status_t) blade_handle_transport_registration_create(blade_handle_transport_registration_t **bhtrP,
                                                                                                                                   ks_pool_t *pool,
                                                                                                                                   blade_module_t *module,
@@ -93,23 +105,9 @@ KS_DECLARE(ks_status_t) blade_handle_transport_registration_create(blade_handle_
        bhtr->module = module;
        bhtr->callbacks = callbacks;
 
-       *bhtrP = bhtr;
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_handle_transport_registration_destroy(blade_handle_transport_registration_t **bhtrP)
-{
-       blade_handle_transport_registration_t *bhtr = NULL;
-
-       ks_assert(bhtrP);
-
-       bhtr = *bhtrP;
-       *bhtrP = NULL;
+       ks_assert(ks_pool_set_cleanup(pool, bhtr, NULL, blade_handle_transport_registration_cleanup) == KS_STATUS_SUCCESS);
 
-       ks_assert(bhtr);
-
-       ks_pool_free(bhtr->pool, &bhtr);
+       *bhtrP = bhtr;
 
        return KS_STATUS_SUCCESS;
 }
@@ -124,6 +122,23 @@ struct blade_handle_session_state_callback_registration_s {
        blade_session_state_callback_t callback;
 };
 
+static void blade_handle_session_state_callback_registration_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_handle_session_state_callback_registration_t *bhsscr = (blade_handle_session_state_callback_registration_t *)ptr;
+
+       ks_assert(bhsscr);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               ks_pool_free(bhsscr->pool, &bhsscr->id);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
+
 ks_status_t blade_handle_session_state_callback_registration_create(blade_handle_session_state_callback_registration_t **bhsscrP,
                                                                                                                                        ks_pool_t *pool,
                                                                                                                                        void *data,
@@ -144,59 +159,70 @@ ks_status_t blade_handle_session_state_callback_registration_create(blade_handle
        bhsscr->data = data;
        bhsscr->callback = callback;
 
+       ks_assert(ks_pool_set_cleanup(pool, bhsscr, NULL, blade_handle_session_state_callback_registration_cleanup) == KS_STATUS_SUCCESS);
+
        *bhsscrP = bhsscr;
 
        return KS_STATUS_SUCCESS;
 }
 
-ks_status_t blade_handle_session_state_callback_registration_destroy(blade_handle_session_state_callback_registration_t **bhsscrP)
+static void blade_handle_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
 {
-       blade_handle_session_state_callback_registration_t *bhsscr = NULL;
-
-       ks_assert(bhsscrP);
-
-       bhsscr = *bhsscrP;
-       *bhsscrP = NULL;
+       blade_handle_t *bh = (blade_handle_t *)ptr;
+       ks_hash_iterator_t *it = NULL;
 
-       ks_assert(bhsscr);
+       ks_assert(bh);
 
-       ks_pool_free(bhsscr->pool, &bhsscr->id);
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               while ((it = ks_hash_first(bh->modules, KS_UNLOCKED)) != NULL) {
+                       void *key = NULL;
+                       blade_module_t *value = NULL;
 
-       ks_pool_free(bhsscr->pool, &bhsscr);
+                       ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
+                       ks_hash_remove(bh->modules, key);
 
-       return KS_STATUS_SUCCESS;
+                       blade_module_destroy(&value); // must call destroy to close the module pool, FREE_VALUE would attempt to free the module from the main handle pool used for the modules hash
+               }
+               ks_thread_pool_destroy(&bh->tpool);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
 }
 
-
-
-KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *pool, ks_thread_pool_t *tpool)
+KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP)
 {
        bhpvt_flag_t newflags = BH_NONE;
        blade_handle_t *bh = NULL;
+       ks_pool_t *pool = NULL;
+       ks_thread_pool_t *tpool = NULL;
 
        ks_assert(bhP);
 
-       if (!pool) {
-               newflags |= BH_MYPOOL;
-               ks_pool_open(&pool);
-       }
-    if (!tpool) {
-               newflags |= BH_MYTPOOL;
-               ks_thread_pool_create(&tpool, BLADE_HANDLE_TPOOL_MIN, BLADE_HANDLE_TPOOL_MAX, BLADE_HANDLE_TPOOL_STACK, KS_PRI_NORMAL, BLADE_HANDLE_TPOOL_IDLE);
-               ks_assert(tpool);
-       }
+       ks_pool_open(&pool);
+       ks_assert(pool);
+
+       ks_thread_pool_create(&tpool, BLADE_HANDLE_TPOOL_MIN, BLADE_HANDLE_TPOOL_MAX, BLADE_HANDLE_TPOOL_STACK, KS_PRI_NORMAL, BLADE_HANDLE_TPOOL_IDLE);
+       ks_assert(tpool);
 
        bh = ks_pool_alloc(pool, sizeof(blade_handle_t));
        bh->flags = newflags;
        bh->pool = pool;
        bh->tpool = tpool;
 
-       // @todo this needs to be reviewed, NOLOCK is incorrect, but RWLOCK causes deadlock somewhere
-       ks_hash_create(&bh->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+       ks_hash_create(&bh->modules, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+       ks_assert(bh->modules);
+
+       ks_hash_create(&bh->transports, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, bh->pool);
        ks_assert(bh->transports);
+
        ks_hash_create(&bh->spaces, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
        ks_assert(bh->spaces);
-       ks_hash_create(&bh->events, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+
+       ks_hash_create(&bh->events, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, bh->pool);
        ks_assert(bh->events);
 
        ks_hash_create(&bh->connections, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
@@ -204,12 +230,14 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
 
        ks_hash_create(&bh->sessions, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
        ks_assert(bh->sessions);
-       ks_hash_create(&bh->session_state_callbacks, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
+       ks_hash_create(&bh->session_state_callbacks, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_VALUE, bh->pool);
        ks_assert(bh->session_state_callbacks);
 
        ks_hash_create(&bh->requests, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, bh->pool);
        ks_assert(bh->requests);
 
+       ks_assert(ks_pool_set_cleanup(pool, bh, NULL, blade_handle_cleanup) == KS_STATUS_SUCCESS);
+
        *bhP = bh;
 
        ks_log(KS_LOG_DEBUG, "Created\n");
@@ -220,7 +248,6 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *poo
 KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
 {
        blade_handle_t *bh = NULL;
-       bhpvt_flag_t flags;
        ks_pool_t *pool;
 
        ks_assert(bhP);
@@ -230,73 +257,57 @@ KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
 
        ks_assert(bh);
 
-       flags = bh->flags;
        pool = bh->pool;
 
+       // shutdown cannot happen inside of the cleanup callback because it'll lock a mutex for the pool during cleanup callbacks which connections and sessions need to finish their cleanup
        blade_handle_shutdown(bh);
 
-       ks_hash_destroy(&bh->requests);
-       ks_hash_destroy(&bh->session_state_callbacks);
-       ks_hash_destroy(&bh->sessions);
-       ks_hash_destroy(&bh->connections);
-       ks_hash_destroy(&bh->events);
-       ks_hash_destroy(&bh->spaces);
-       ks_hash_destroy(&bh->transports);
-
-    if (bh->tpool && (flags & BH_MYTPOOL)) ks_thread_pool_destroy(&bh->tpool);
-
-       ks_log(KS_LOG_DEBUG, "Destroyed\n");
-
-       ks_pool_free(bh->pool, &bh);
-
-       if (pool && (flags & BH_MYPOOL)) {
-               ks_pool_close(&pool);
-       }
+       ks_pool_close(&pool);
 
        return KS_STATUS_SUCCESS;
 }
 
 ks_status_t blade_handle_config(blade_handle_t *bh, config_setting_t *config)
 {
-       config_setting_t *directory = NULL;
-       config_setting_t *datastore = NULL;
-
        ks_assert(bh);
 
        if (!config) return KS_STATUS_FAIL;
     if (!config_setting_is_group(config)) return KS_STATUS_FAIL;
 
-       directory = config_setting_get_member(config, "directory");
-
-    datastore = config_setting_get_member(config, "datastore");
-    //if (datastore && !config_setting_is_group(datastore)) return KS_STATUS_FAIL;
-
-
-       bh->config_directory = directory;
-       bh->config_datastore = datastore;
-
        return KS_STATUS_SUCCESS;
 }
 
 KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config)
 {
+       blade_module_t *module = NULL;
+       ks_hash_iterator_t *it = NULL;
+
        ks_assert(bh);
 
+       // register internal modules
+       blade_module_wss_create(&module, bh);
+       ks_assert(module);
+       blade_handle_module_register(module);
+
+
     if (blade_handle_config(bh, config) != KS_STATUS_SUCCESS) {
                ks_log(KS_LOG_DEBUG, "blade_handle_config failed\n");
                return KS_STATUS_FAIL;
        }
 
-       if (bh->config_datastore && !blade_handle_datastore_available(bh)) {
-               blade_datastore_create(&bh->datastore, bh->pool, bh->tpool);
-               ks_assert(bh->datastore);
-               if (blade_datastore_startup(bh->datastore, bh->config_datastore) != KS_STATUS_SUCCESS) {
-                       ks_log(KS_LOG_DEBUG, "blade_datastore_startup failed\n");
-                       return KS_STATUS_FAIL;
-               }
-       }
 
-       // @todo load internal modules, call onload and onstartup
+       for (it = ks_hash_first(bh->modules, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
+               void *key = NULL;
+               blade_module_t *value = NULL;
+               blade_module_callbacks_t *callbacks = NULL;
+
+               ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
+
+               callbacks = blade_module_callbacks_get(value);
+               ks_assert(callbacks);
+
+               if (callbacks->onstartup) callbacks->onstartup(value, config);
+       }
 
        return KS_STATUS_SUCCESS;
 }
@@ -307,53 +318,46 @@ KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh)
 
        ks_assert(bh);
 
-       // @todo call onshutdown for internal modules
-
-       // @todo repeat the same as below for connections, this will catch all including those that have not yet been attached to a session for edge case cleanup
-
-       ks_hash_read_lock(bh->sessions);
-       for (it = ks_hash_first(bh->sessions, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
+       ks_hash_read_lock(bh->modules);
+       for (it = ks_hash_first(bh->modules, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
                void *key = NULL;
-               blade_session_t *value = NULL;
+               blade_module_t *value = NULL;
+               blade_module_callbacks_t *callbacks = NULL;
 
                ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
 
-               blade_session_hangup(value);
-       }
-       ks_hash_read_unlock(bh->sessions);
-       while (ks_hash_count(bh->sessions) > 0) ks_sleep_ms(100);
-
+               callbacks = blade_module_callbacks_get(value);
+               ks_assert(callbacks);
 
-       // @todo call onunload for internal modules
+               if (callbacks->onshutdown) callbacks->onshutdown(value);
+       }
+       ks_hash_read_unlock(bh->modules);
 
-       while ((it = ks_hash_first(bh->requests, KS_UNLOCKED))) {
+       ks_hash_read_lock(bh->connections);
+       for (it = ks_hash_first(bh->connections, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
                void *key = NULL;
-               blade_request_t *value = NULL;
+               blade_connection_t *value = NULL;
 
                ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
-               ks_hash_remove(bh->requests, key);
 
-               blade_request_destroy(&value);
+               blade_connection_disconnect(value);
        }
+       ks_hash_read_unlock(bh->connections);
+       while (ks_hash_count(bh->connections) > 0) ks_sleep_ms(100);
 
-       while ((it = ks_hash_first(bh->events, KS_UNLOCKED))) {
+       ks_hash_read_lock(bh->sessions);
+       for (it = ks_hash_first(bh->sessions, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
                void *key = NULL;
-               blade_event_callback_t *value = NULL;
+               blade_session_t *value = NULL;
 
                ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
-               blade_handle_event_unregister(bh, (const char *)key);
-       }
 
-       while ((it = ks_hash_first(bh->spaces, KS_UNLOCKED))) {
-               void *key = NULL;
-               blade_space_t *value = NULL;
-
-               ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
-               blade_handle_space_unregister(value);
+               blade_session_hangup(value);
        }
+       ks_hash_read_unlock(bh->sessions);
+       while (ks_hash_count(bh->sessions) > 0) ks_sleep_ms(100);
 
-       // @todo unload DSOs
-
+       // @todo old code, datastore will be completely revamped under the new architecture
        if (blade_handle_datastore_available(bh)) blade_datastore_destroy(&bh->datastore);
 
        return KS_STATUS_SUCCESS;
@@ -371,28 +375,44 @@ KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh)
        return bh->tpool;
 }
 
+KS_DECLARE(ks_status_t) blade_handle_module_register(blade_module_t *bm)
+{
+       blade_handle_t *bh = NULL;
+       const char *id = NULL;
+
+       ks_assert(bm);
+
+       bh = blade_module_handle_get(bm);
+       ks_assert(bh);
+
+       id = blade_module_id_get(bm);
+       ks_assert(id);
+
+       ks_hash_insert(bh->modules, (void *)id, bm);
+
+       ks_log(KS_LOG_DEBUG, "Module Registered\n");
+
+       return KS_STATUS_SUCCESS;
+}
+
+
 KS_DECLARE(ks_status_t) blade_handle_transport_register(blade_handle_t *bh, blade_module_t *bm, const char *name, blade_transport_callbacks_t *callbacks)
 {
        blade_handle_transport_registration_t *bhtr = NULL;
-       blade_handle_transport_registration_t *bhtr_old = NULL;
+       char *key = NULL;
 
        ks_assert(bh);
        ks_assert(bm);
        ks_assert(name);
        ks_assert(callbacks);
 
-       // @todo reduce blade_handle_t parameter, pull from blade_module_t parameter
-
        blade_handle_transport_registration_create(&bhtr, bh->pool, bm, callbacks);
        ks_assert(bhtr);
 
-       ks_hash_write_lock(bh->transports);
-       bhtr_old = ks_hash_search(bh->transports, (void *)name, KS_UNLOCKED);
-       if (bhtr_old) ks_hash_remove(bh->transports, (void *)name);
-       ks_hash_insert(bh->transports, (void *)name, bhtr);
-       ks_hash_write_unlock(bh->transports);
+       key = ks_pstrdup(bh->pool, name);
+       ks_assert(key);
 
-       if (bhtr_old) blade_handle_transport_registration_destroy(&bhtr_old);
+       ks_hash_insert(bh->transports, (void *)key, bhtr);
 
        ks_log(KS_LOG_DEBUG, "Transport Registered: %s\n", name);
 
@@ -401,20 +421,12 @@ KS_DECLARE(ks_status_t) blade_handle_transport_register(blade_handle_t *bh, blad
 
 KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_handle_t *bh, const char *name)
 {
-       blade_handle_transport_registration_t *bhtr = NULL;
-
        ks_assert(bh);
        ks_assert(name);
 
-       ks_hash_write_lock(bh->transports);
-       bhtr = ks_hash_search(bh->transports, (void *)name, KS_UNLOCKED);
-       if (bhtr) ks_hash_remove(bh->transports, (void *)name);
-       ks_hash_write_unlock(bh->transports);
+       ks_log(KS_LOG_DEBUG, "Transport Unregistered: %s\n", name);
 
-       if (bhtr) {
-               blade_handle_transport_registration_destroy(&bhtr);
-               ks_log(KS_LOG_DEBUG, "Transport Unregistered: %s\n", name);
-       }
+       ks_hash_remove(bh->transports, (void *)name);
 
        return KS_STATUS_SUCCESS;
 }
@@ -423,7 +435,6 @@ KS_DECLARE(ks_status_t) blade_handle_space_register(blade_space_t *bs)
 {
        blade_handle_t *bh = NULL;
        const char *path = NULL;
-       blade_space_t *bs_old = NULL;
 
        ks_assert(bs);
 
@@ -433,13 +444,7 @@ KS_DECLARE(ks_status_t) blade_handle_space_register(blade_space_t *bs)
        path = blade_space_path_get(bs);
        ks_assert(path);
 
-       ks_hash_write_lock(bh->spaces);
-       bs_old = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
-       if (bs_old) ks_hash_remove(bh->spaces, (void *)path);
        ks_hash_insert(bh->spaces, (void *)path, bs);
-       ks_hash_write_unlock(bh->spaces);
-
-       if (bs_old) blade_space_destroy(&bs_old);
 
        ks_log(KS_LOG_DEBUG, "Space Registered: %s\n", path);
 
@@ -459,14 +464,9 @@ KS_DECLARE(ks_status_t) blade_handle_space_unregister(blade_space_t *bs)
        path = blade_space_path_get(bs);
        ks_assert(path);
 
-       ks_hash_write_lock(bh->spaces);
-       ks_hash_remove(bh->spaces, (void *)path);
-       ks_hash_write_unlock(bh->spaces);
+       ks_log(KS_LOG_DEBUG, "Space Unregistered: %s\n", path);
 
-       if (bs) {
-               ks_log(KS_LOG_DEBUG, "Space Unregistered: %s\n", path);
-               blade_space_destroy(&bs);
-       }
+       ks_hash_remove(bh->spaces, (void *)path);
 
        return KS_STATUS_SUCCESS;
 }
@@ -478,8 +478,7 @@ KS_DECLARE(blade_space_t *) blade_handle_space_lookup(blade_handle_t *bh, const
        ks_assert(bh);
        ks_assert(path);
 
-       ks_hash_read_lock(bh->spaces);
-       bs = ks_hash_search(bh->spaces, (void *)path, KS_UNLOCKED);
+       bs = ks_hash_search(bh->spaces, (void *)path, KS_READLOCKED);
        ks_hash_read_unlock(bh->spaces);
 
        return bs;
@@ -487,13 +486,16 @@ KS_DECLARE(blade_space_t *) blade_handle_space_lookup(blade_handle_t *bh, const
 
 KS_DECLARE(ks_status_t) blade_handle_event_register(blade_handle_t *bh, const char *event, blade_event_callback_t callback)
 {
+       char *key = NULL;
+
        ks_assert(bh);
        ks_assert(event);
        ks_assert(callback);
 
-       ks_hash_write_lock(bh->events);
-       ks_hash_insert(bh->events, (void *)event, (void *)(intptr_t)callback);
-       ks_hash_write_unlock(bh->events);
+       key = ks_pstrdup(bh->pool, event);
+       ks_assert(key);
+
+       ks_hash_insert(bh->events, (void *)key, (void *)(intptr_t)callback);
 
        ks_log(KS_LOG_DEBUG, "Event Registered: %s\n", event);
 
@@ -502,18 +504,12 @@ KS_DECLARE(ks_status_t) blade_handle_event_register(blade_handle_t *bh, const ch
 
 KS_DECLARE(ks_status_t) blade_handle_event_unregister(blade_handle_t *bh, const char *event)
 {
-       ks_bool_t removed = KS_FALSE;
-
        ks_assert(bh);
        ks_assert(event);
 
-       ks_hash_write_lock(bh->events);
-       if (ks_hash_remove(bh->events, (void *)event)) removed = KS_TRUE;
-       ks_hash_write_unlock(bh->events);
+       ks_log(KS_LOG_DEBUG, "Event Unregistered: %s\n", event);
 
-       if (removed) {
-               ks_log(KS_LOG_DEBUG, "Event Unregistered: %s\n", event);
-       }
+       ks_hash_remove(bh->events, (void *)event);
 
        return KS_STATUS_SUCCESS;
 }
@@ -525,8 +521,7 @@ KS_DECLARE(blade_event_callback_t) blade_handle_event_lookup(blade_handle_t *bh,
        ks_assert(bh);
        ks_assert(event);
 
-       ks_hash_read_lock(bh->events);
-       callback = (blade_event_callback_t)(intptr_t)ks_hash_search(bh->events, (void *)event, KS_UNLOCKED);
+       callback = (blade_event_callback_t)(intptr_t)ks_hash_search(bh->events, (void *)event, KS_READLOCKED);
        ks_hash_read_unlock(bh->events);
 
        return callback;
@@ -725,7 +720,6 @@ KS_DECLARE(void) blade_handle_sessions_send(blade_handle_t *bh, ks_list_t *sessi
 
 KS_DECLARE(ks_status_t) blade_handle_session_state_callback_register(blade_handle_t *bh, void *data, blade_session_state_callback_t callback, const char **id)
 {
-       ks_status_t ret = KS_STATUS_SUCCESS;
        blade_handle_session_state_callback_registration_t *bhsscr = NULL;
 
        ks_assert(bh);
@@ -735,31 +729,21 @@ KS_DECLARE(ks_status_t) blade_handle_session_state_callback_register(blade_handl
        blade_handle_session_state_callback_registration_create(&bhsscr, blade_handle_pool_get(bh), data, callback);
        ks_assert(bhsscr);
 
-       ks_hash_write_lock(bh->session_state_callbacks);
-       ret = ks_hash_insert(bh->session_state_callbacks, (void *)bhsscr->id, bhsscr);
-       ks_hash_write_unlock(bh->session_state_callbacks);
+       ks_hash_insert(bh->session_state_callbacks, (void *)bhsscr->id, bhsscr);
 
        *id = bhsscr->id;
 
-       return ret;
+       return KS_STATUS_SUCCESS;
 }
 
 KS_DECLARE(ks_status_t) blade_handle_session_state_callback_unregister(blade_handle_t *bh, const char *id)
 {
-       ks_status_t ret = KS_STATUS_SUCCESS;
-       blade_handle_session_state_callback_registration_t *bhsscr = NULL;
-
        ks_assert(bh);
        ks_assert(id);
 
-       ks_hash_write_lock(bh->session_state_callbacks);
-       bhsscr = (blade_handle_session_state_callback_registration_t *)ks_hash_remove(bh->session_state_callbacks, (void *)id);
-       if (!bhsscr) ret = KS_STATUS_FAIL;
-       ks_hash_write_unlock(bh->session_state_callbacks);
-
-       if (bhsscr)     blade_handle_session_state_callback_registration_destroy(&bhsscr);
+       ks_hash_remove(bh->session_state_callbacks, (void *)id);
 
-       return ret;
+       return KS_STATUS_SUCCESS;
 }
 
 KS_DECLARE(void) blade_handle_session_state_callbacks_execute(blade_session_t *bs, blade_session_state_condition_t condition)
@@ -789,21 +773,19 @@ KS_DECLARE(void) blade_handle_session_state_callbacks_execute(blade_session_t *b
 
 KS_DECLARE(blade_request_t *) blade_handle_requests_get(blade_handle_t *bh, const char *mid)
 {
-       blade_request_t *br = NULL;
+       blade_request_t *breq = NULL;
 
        ks_assert(bh);
        ks_assert(mid);
 
-       ks_hash_read_lock(bh->requests);
-       br = ks_hash_search(bh->requests, (void *)mid, KS_UNLOCKED);
+       breq = ks_hash_search(bh->requests, (void *)mid, KS_READLOCKED);
        ks_hash_read_unlock(bh->requests);
 
-       return br;
+       return breq;
 }
 
 KS_DECLARE(ks_status_t) blade_handle_requests_add(blade_request_t *br)
 {
-       ks_status_t ret = KS_STATUS_SUCCESS;
        blade_handle_t *bh = NULL;
 
        ks_assert(br);
@@ -811,16 +793,13 @@ KS_DECLARE(ks_status_t) blade_handle_requests_add(blade_request_t *br)
        bh = br->handle;
        ks_assert(bh);
 
-       ks_hash_write_lock(bh->requests);
-       ret = ks_hash_insert(bh->requests, (void *)br->message_id, br);
-       ks_hash_write_unlock(bh->requests);
+       ks_hash_insert(bh->requests, (void *)br->message_id, br);
 
-       return ret;
+       return KS_STATUS_SUCCESS;
 }
 
 KS_DECLARE(ks_status_t) blade_handle_requests_remove(blade_request_t *br)
 {
-       ks_status_t ret = KS_STATUS_SUCCESS;
        blade_handle_t *bh = NULL;
 
        ks_assert(br);
@@ -828,11 +807,9 @@ KS_DECLARE(ks_status_t) blade_handle_requests_remove(blade_request_t *br)
        bh = br->handle;
        ks_assert(bh);
 
-       ks_hash_write_lock(bh->requests);
-       if (ks_hash_remove(bh->requests, (void *)br->message_id) == NULL) ret = KS_STATUS_FAIL;
-       ks_hash_write_unlock(bh->requests);
+       ks_hash_remove(bh->requests, (void *)br->message_id);
 
-       return ret;
+       return KS_STATUS_SUCCESS;
 }
 
 
index f2b527689e080bdbd6ce51b1f10d8a863901d951..ce92ad7296c9a3bd9c324e3bbf789a0eb8715a25 100644 (file)
@@ -51,6 +51,8 @@
 #include "ks_dht.h"
 #include "ks_bencode.h"
 
+#include "blade_module_wss.h"
+
 KS_BEGIN_EXTERN_C
 
 #ifdef _WIN32
index 74bf87d13f91ab13aefc6d43b5776d563ca2d99a..f2ab8ab548ce54fa57e95fc6054ff7d067fc6ff6 100644 (file)
@@ -37,7 +37,6 @@
 
 KS_BEGIN_EXTERN_C
 KS_DECLARE(ks_status_t) blade_method_create(blade_method_t **bmP, blade_space_t *bs, const char *name, blade_request_callback_t callback);
-KS_DECLARE(ks_status_t) blade_method_destroy(blade_method_t **bmP);
 KS_DECLARE(const char *) blade_method_name_get(blade_method_t *bm);
 KS_DECLARE(blade_request_callback_t) blade_method_callback_get(blade_method_t *bm);
 KS_END_EXTERN_C
index ff2b942f4811029dc6e756fcf4f428098a0b9d9b..20f905b7ea590da69b52f839c98ecc83dd5b8986 100644 (file)
 #include <blade.h>
 
 KS_BEGIN_EXTERN_C
+
 KS_DECLARE(ks_status_t) blade_module_create(blade_module_t **bmP, blade_handle_t *bh, ks_pool_t *pool, void *module_data, blade_module_callbacks_t *module_callbacks);
+KS_DECLARE(ks_status_t) blade_module_destroy(blade_module_t **bmP);
 KS_DECLARE(blade_handle_t *) blade_module_handle_get(blade_module_t *bm);
+KS_DECLARE(ks_pool_t *) blade_module_pool_get(blade_module_t *bm);
+KS_DECLARE(const char *) blade_module_id_get(blade_module_t *bm);
 KS_DECLARE(void *) blade_module_data_get(blade_module_t *bm);
+KS_DECLARE(blade_module_callbacks_t *) blade_module_callbacks_get(blade_module_t *bm);
 
-// @todo very temporary, this is just here to get the wss module loaded until DSO is in place
-KS_DECLARE(ks_status_t) blade_module_wss_on_load(blade_module_t **bmP, blade_handle_t *bh);
-KS_DECLARE(ks_status_t) blade_module_wss_on_unload(blade_module_t *bm);
-KS_DECLARE(ks_status_t) blade_module_wss_on_startup(blade_module_t *bm, config_setting_t *config);
-KS_DECLARE(ks_status_t) blade_module_wss_on_shutdown(blade_module_t *bm);
-
-KS_DECLARE(ks_status_t) blade_module_chat_on_load(blade_module_t **bmP, blade_handle_t *bh);
-KS_DECLARE(ks_status_t) blade_module_chat_on_unload(blade_module_t *bm);
-KS_DECLARE(ks_status_t) blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config);
-KS_DECLARE(ks_status_t) blade_module_chat_on_shutdown(blade_module_t *bm);
 KS_END_EXTERN_C
 
 #endif
diff --git a/libs/libblade/src/include/blade_module_wss.h b/libs/libblade/src/include/blade_module_wss.h
new file mode 100644 (file)
index 0000000..fba23a5
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, Shane Bryldt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _BLADE_MODULE_WSS_H_
+#define _BLADE_MODULE_WSS_H_
+#include <blade.h>
+
+KS_BEGIN_EXTERN_C
+
+KS_DECLARE(ks_status_t) blade_module_wss_create(blade_module_t **bmP, blade_handle_t *bh);
+
+KS_DECLARE(ks_status_t) blade_module_wss_on_startup(blade_module_t *bm, config_setting_t *config);
+KS_DECLARE(ks_status_t) blade_module_wss_on_shutdown(blade_module_t *bm);
+
+KS_END_EXTERN_C
+
+#endif
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+ */
index 0a8b97afb0d7f6b828f939dcedb2b734c7b4f36d..29c8814d387cf4ca613a8ee54f5cae5771b5c242 100644 (file)
 KS_BEGIN_EXTERN_C
 KS_DECLARE(ks_status_t) blade_request_create(blade_request_t **breqP,
                                                                                         blade_handle_t *bh,
+                                                                                        ks_pool_t *pool,
                                                                                         const char *session_id,
                                                                                         cJSON *json,
                                                                                         blade_response_callback_t callback);
 KS_DECLARE(ks_status_t) blade_request_destroy(blade_request_t **breqP);
-KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP, blade_handle_t *bh, const char *session_id, blade_request_t *breq, cJSON *json);
+KS_DECLARE(ks_status_t) blade_response_create(blade_response_t **bresP, blade_handle_t *bh, ks_pool_t *pool, const char *session_id, blade_request_t *breq, cJSON *json);
 KS_DECLARE(ks_status_t) blade_response_destroy(blade_response_t **bresP);
-KS_DECLARE(ks_status_t) blade_event_create(blade_event_t **bevP, blade_handle_t *bh, const char *session_id, cJSON *json);
+KS_DECLARE(ks_status_t) blade_event_create(blade_event_t **bevP, blade_handle_t *bh, ks_pool_t *pool, const char *session_id, cJSON *json);
 KS_DECLARE(ks_status_t) blade_event_destroy(blade_event_t **bevP);
 KS_DECLARE(ks_status_t) blade_rpc_request_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method);
 KS_DECLARE(ks_status_t) blade_rpc_response_create(cJSON **json, cJSON **result, const char *id);
index bf241e45c9c1b88ab4a66188fdb1661eec5c0b94..0165a3fa6854f40f9a53a867ea2b678dbca29d0d 100644 (file)
@@ -37,8 +37,8 @@
 
 KS_BEGIN_EXTERN_C
 KS_DECLARE(ks_status_t) blade_space_create(blade_space_t **bsP, blade_handle_t *bh, blade_module_t *bm, const char *path);
-KS_DECLARE(ks_status_t) blade_space_destroy(blade_space_t **bsP);
 KS_DECLARE(blade_handle_t *) blade_space_handle_get(blade_space_t *bs);
+KS_DECLARE(ks_pool_t *) blade_space_pool_get(blade_space_t *bs);
 KS_DECLARE(blade_module_t *) blade_space_module_get(blade_space_t *bs);
 KS_DECLARE(const char *) blade_space_path_get(blade_space_t *bs);
 KS_DECLARE(ks_status_t) blade_space_methods_add(blade_space_t *bs, blade_method_t *bm);
index d8ad0aadec4a13841450edfa056e28e714924c7e..e8c10fbc84875aea081668d99c3842d7fd21461f 100644 (file)
 
 KS_BEGIN_EXTERN_C
 KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP);
-KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP, ks_pool_t *pool, ks_thread_pool_t *tpool);
+KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP);
 KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_t *config);
 KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh);
 KS_DECLARE(ks_pool_t *) blade_handle_pool_get(blade_handle_t *bh);
 KS_DECLARE(ks_thread_pool_t *) blade_handle_tpool_get(blade_handle_t *bh);
 
+KS_DECLARE(ks_status_t) blade_handle_module_register(blade_module_t *bm);
+//KS_DECLARE(ks_status_t) blade_handle_module_unregister(blade_module_t *bm);
+
 KS_DECLARE(ks_status_t) blade_handle_transport_register(blade_handle_t *bh, blade_module_t *bm, const char *name, blade_transport_callbacks_t *callbacks);
 KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_handle_t *bh, const char *name);
 
index 6bd23134e5987388bbd2330bdfd1f11f62961a6b..0146a9aa5e0dd66fb75437ed53303570153e04f5 100644 (file)
@@ -116,14 +116,10 @@ typedef enum {
 
 
 
-typedef ks_status_t (*blade_module_load_callback_t)(blade_module_t **bmP, blade_handle_t *bh);
-typedef ks_status_t (*blade_module_unload_callback_t)(blade_module_t *bm);
 typedef ks_status_t (*blade_module_startup_callback_t)(blade_module_t *bm, config_setting_t *config);
-typedef ks_status_t (*blade_module_shutdown_callback_t)(blade_module_t *bm);
+typedef ks_status_t(*blade_module_shutdown_callback_t)(blade_module_t *bm);
 
 struct blade_module_callbacks_s {
-       blade_module_load_callback_t onload;
-       blade_module_unload_callback_t onunload;
        blade_module_startup_callback_t onstartup;
        blade_module_shutdown_callback_t onshutdown;
 };
index 61c373ee5f8665d58557c90f3a72d14fb2cf93e2..3be2aa3b5a1e63ac65791d2bfbe19ab3f7733fca 100644 (file)
@@ -93,7 +93,7 @@ struct bencode_type {
        struct bencode *(*decode) (struct ben_decode_ctx *ctx);
        int (*encode) (struct ben_encode_ctx *ctx, const struct bencode *b);
        size_t (*get_size) (const struct bencode *b);
-       void (*free) (struct bencode *b);
+       void (*freer) (struct bencode *b);
        int (*cmp) (const struct bencode *a, const struct bencode *b);
 };
 
index 24ff8fe7b653a0f622831917f5b4d89f06785a01..b3ffc36bc669b8f42c8187b4599bbf22566156e0 100644 (file)
@@ -1715,8 +1715,8 @@ void ben_free(struct bencode *b)
                break;
        case BENCODE_USER:
                u = ben_user_cast(b);
-               if (u->info->free)
-                       u->info->free(b);
+               if (u->info->freer)
+                       u->info->freer(b);
                break;
        default:
                die("invalid type: %d\n", b->type);
index c5f8c010659dca7f5715e12ac0e6d1b0bb544e3a..d686c7e305bd98eb4130e6a7247bc16daf5da7be 100644 (file)
@@ -37,7 +37,7 @@ int main(int argc, char **argv)
        config_t config;
        config_setting_t *config_blade = NULL;
        blade_module_t *mod_wss = NULL;
-       //blade_identity_t *id = NULL;
+       blade_identity_t *id = NULL;
        const char *cfgpath = "bladec.cfg";
        const char *session_state_callback_id = NULL;
 
@@ -45,7 +45,7 @@ int main(int argc, char **argv)
 
        blade_init();
 
-       blade_handle_create(&bh, NULL, NULL);
+       blade_handle_create(&bh);
 
        if (argc > 1) cfgpath = argv[1];
 
@@ -71,26 +71,17 @@ int main(int argc, char **argv)
                return EXIT_FAILURE;
        }
 
-       if (blade_module_wss_on_load(&mod_wss, bh) != KS_STATUS_SUCCESS) {
-               ks_log(KS_LOG_ERROR, "Blade WSS module load failed\n");
-               return EXIT_FAILURE;
-       }
-       if (blade_module_wss_on_startup(mod_wss, config_blade) != KS_STATUS_SUCCESS) {
-               ks_log(KS_LOG_ERROR, "Blade WSS module startup failed\n");
-               return EXIT_FAILURE;
-       }
-
        blade_handle_event_register(bh, "blade.chat.message", on_blade_chat_message_event);
        blade_handle_session_state_callback_register(bh, NULL, on_blade_session_state_callback, &session_state_callback_id);
 
        loop(bh);
 
-       blade_handle_session_state_callback_unregister(bh, session_state_callback_id);
-
-       blade_module_wss_on_unload(mod_wss);
+       //blade_handle_session_state_callback_unregister(bh, session_state_callback_id);
 
        blade_handle_destroy(&bh);
 
+       config_destroy(&config);
+
        blade_shutdown();
 
        return 0;
@@ -120,10 +111,10 @@ void on_blade_session_state_callback(blade_session_t *bs, blade_session_state_co
        if (condition == BLADE_SESSION_STATE_CONDITION_PRE) {
                ks_log(KS_LOG_DEBUG, "Blade Session State Changed: %s, %d\n", blade_session_id_get(bs), state);
                if (state == BLADE_SESSION_STATE_READY) {
-                       //cJSON *req = NULL;
-                       //blade_rpc_request_create(blade_session_pool_get(bs), &req, NULL, NULL, "blade.chat.join");
-                       //blade_session_send(bs, req, on_blade_chat_join_response);
-                       //cJSON_Delete(req);
+                       cJSON *req = NULL;
+                       blade_rpc_request_create(blade_handle_pool_get(blade_session_handle_get(bs)), &req, NULL, NULL, "blade.chat.join");
+                       blade_session_send(bs, req, on_blade_chat_join_response);
+                       cJSON_Delete(req);
                }
        }
 }
@@ -186,7 +177,7 @@ void process_console_input(blade_handle_t *bh, char *line)
 
 void command_quit(blade_handle_t *bh, char *args)
 {
-       ks_assert(bh);
+       //ks_assert(bh);
        ks_assert(args);
 
        ks_log(KS_LOG_DEBUG, "Shutting down\n");
index 42af3a8448b0ede49d33d46d2e862753e4bbc8b3..1253085374525a672cf000696f87fa71d74549c2 100644 (file)
@@ -23,13 +23,45 @@ static const struct command_def_s command_defs[] = {
        { NULL, NULL }
 };
 
+
+
+ks_status_t blade_module_chat_create(blade_module_t **bmP, blade_handle_t *bh);
+ks_status_t blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config);
+ks_status_t blade_module_chat_on_shutdown(blade_module_t *bm);
+
+typedef struct blade_module_chat_s blade_module_chat_t;
+struct blade_module_chat_s {
+       blade_handle_t *handle;
+       ks_pool_t *pool;
+       ks_thread_pool_t *tpool;
+       blade_module_t *module;
+       //blade_module_callbacks_t *module_callbacks;
+
+       blade_space_t *blade_chat_space;
+       const char *session_state_callback_id;
+       ks_list_t *participants;
+};
+
+void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
+
+ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq);
+ks_bool_t blade_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq);
+ks_bool_t blade_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq);
+
+static blade_module_callbacks_t g_module_chat_callbacks =
+{
+       blade_module_chat_on_startup,
+       blade_module_chat_on_shutdown,
+};
+
+
 int main(int argc, char **argv)
 {
        blade_handle_t *bh = NULL;
        config_t config;
        config_setting_t *config_blade = NULL;
        blade_module_t *mod_wss = NULL;
-       //blade_module_t *mod_chat = NULL;
+       blade_module_t *mod_chat = NULL;
        //blade_identity_t *id = NULL;
        const char *cfgpath = "blades.cfg";
 
@@ -37,7 +69,7 @@ int main(int argc, char **argv)
 
        blade_init();
 
-       blade_handle_create(&bh, NULL, NULL);
+       blade_handle_create(&bh);
 
        if (argc > 1) cfgpath = argv[1];
 
@@ -58,32 +90,21 @@ int main(int argc, char **argv)
                return EXIT_FAILURE;
        }
 
+       // must occur before startup
+       blade_module_chat_create(&mod_chat, bh);
+       blade_handle_module_register(mod_chat);
+
        if (blade_handle_startup(bh, config_blade) != KS_STATUS_SUCCESS) {
                ks_log(KS_LOG_ERROR, "Blade startup failed\n");
                return EXIT_FAILURE;
        }
 
-       if (blade_module_wss_on_load(&mod_wss, bh) != KS_STATUS_SUCCESS) {
-               ks_log(KS_LOG_ERROR, "Blade WSS module load failed\n");
-               return EXIT_FAILURE;
-       }
-       if (blade_module_wss_on_startup(mod_wss, config_blade) != KS_STATUS_SUCCESS) {
-               ks_log(KS_LOG_ERROR, "Blade WSS module startup failed\n");
-               return EXIT_FAILURE;
-       }
-
-       //blade_module_chat_on_load(&mod_chat, bh);
-       //blade_module_chat_on_startup(mod_chat, config_blade);
-
        loop(bh);
 
-       //blade_module_chat_on_shutdown(mod_chat);
-       //blade_module_chat_on_unload(mod_chat);
-
-       blade_module_wss_on_unload(mod_wss);
-
        blade_handle_destroy(&bh);
 
+       config_destroy(&config);
+
        blade_shutdown();
 
        return 0;
@@ -153,3 +174,340 @@ void command_quit(blade_handle_t *bh, char *args)
        ks_log(KS_LOG_DEBUG, "Shutting down\n");
        g_shutdown = KS_TRUE;
 }
+
+
+
+
+static void blade_module_chat_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_module_chat_t *bm_chat = (blade_module_chat_t *)ptr;
+
+       ks_assert(bm_chat);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
+
+
+ks_status_t blade_module_chat_create(blade_module_t **bmP, blade_handle_t *bh)
+{
+       blade_module_chat_t *bm_chat = NULL;
+       ks_pool_t *pool = NULL;
+
+       ks_assert(bmP);
+       ks_assert(bh);
+
+       ks_pool_open(&pool);
+       ks_assert(pool);
+
+       bm_chat = ks_pool_alloc(pool, sizeof(blade_module_chat_t));
+       bm_chat->handle = bh;
+       bm_chat->pool = pool;
+       bm_chat->tpool = blade_handle_tpool_get(bh);
+       bm_chat->session_state_callback_id = NULL;
+
+       ks_list_create(&bm_chat->participants, pool);
+       ks_assert(bm_chat->participants);
+
+       blade_module_create(&bm_chat->module, bh, pool, bm_chat, &g_module_chat_callbacks);
+
+       ks_assert(ks_pool_set_cleanup(pool, bm_chat, NULL, blade_module_chat_cleanup) == KS_STATUS_SUCCESS);
+
+       ks_log(KS_LOG_DEBUG, "Created\n");
+
+       *bmP = bm_chat->module;
+
+       return KS_STATUS_SUCCESS;
+}
+
+
+ks_status_t blade_module_chat_config(blade_module_chat_t *bm_chat, config_setting_t *config)
+{
+       config_setting_t *chat = NULL;
+
+       ks_assert(bm_chat);
+       ks_assert(config);
+
+       if (!config_setting_is_group(config)) {
+               ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
+               return KS_STATUS_FAIL;
+       }
+
+       chat = config_setting_get_member(config, "chat");
+       if (chat) {
+       }
+
+
+       // Configuration is valid, now assign it to the variables that are used
+       // If the configuration was invalid, then this does not get changed
+
+       ks_log(KS_LOG_DEBUG, "Configured\n");
+
+       return KS_STATUS_SUCCESS;
+}
+
+ks_status_t blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config)
+{
+       blade_module_chat_t *bm_chat = NULL;
+       blade_space_t *space = NULL;
+       blade_method_t *method = NULL;
+
+       ks_assert(bm);
+       ks_assert(config);
+
+       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
+
+       if (blade_module_chat_config(bm_chat, config) != KS_STATUS_SUCCESS) {
+               ks_log(KS_LOG_DEBUG, "blade_module_chat_config failed\n");
+               return KS_STATUS_FAIL;
+       }
+
+       blade_space_create(&space, bm_chat->handle, bm, "blade.chat");
+       ks_assert(space);
+
+       bm_chat->blade_chat_space = space;
+
+       blade_method_create(&method, space, "join", blade_chat_join_request_handler);
+       ks_assert(method);
+       blade_space_methods_add(space, method);
+
+       blade_method_create(&method, space, "leave", blade_chat_leave_request_handler);
+       ks_assert(method);
+       blade_space_methods_add(space, method);
+
+       blade_method_create(&method, space, "send", blade_chat_send_request_handler);
+       ks_assert(method);
+       blade_space_methods_add(space, method);
+
+       blade_handle_space_register(space);
+
+       blade_handle_session_state_callback_register(blade_module_handle_get(bm), bm, blade_module_chat_on_session_state, &bm_chat->session_state_callback_id);
+
+       ks_log(KS_LOG_DEBUG, "Started\n");
+
+       return KS_STATUS_SUCCESS;
+}
+
+ks_status_t blade_module_chat_on_shutdown(blade_module_t *bm)
+{
+       blade_module_chat_t *bm_chat = NULL;
+
+       ks_assert(bm);
+
+       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
+       ks_assert(bm_chat);
+
+       if (bm_chat->session_state_callback_id) blade_handle_session_state_callback_unregister(blade_module_handle_get(bm), bm_chat->session_state_callback_id);
+       bm_chat->session_state_callback_id = NULL;
+
+       if (bm_chat->blade_chat_space) blade_handle_space_unregister(bm_chat->blade_chat_space);
+
+       ks_log(KS_LOG_DEBUG, "Stopped\n");
+
+       return KS_STATUS_SUCCESS;
+}
+
+void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data)
+{
+       blade_module_t *bm = NULL;
+       blade_module_chat_t *bm_chat = NULL;
+
+       ks_assert(bs);
+       ks_assert(data);
+
+       bm = (blade_module_t *)data;
+       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
+       ks_assert(bm_chat);
+
+       if (blade_session_state_get(bs) == BLADE_SESSION_STATE_HANGUP && condition == BLADE_SESSION_STATE_CONDITION_PRE) {
+               cJSON *props = NULL;
+
+               ks_log(KS_LOG_DEBUG, "Removing session from chat participants if present\n");
+
+               props = blade_session_properties_get(bs);
+               ks_assert(props);
+
+               cJSON_DeleteItemFromObject(props, "blade.chat.participant");
+
+               ks_list_delete(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
+       }
+}
+
+ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq)
+{
+       blade_module_chat_t *bm_chat = NULL;
+       blade_session_t *bs = NULL;
+       cJSON *res = NULL;
+       cJSON *props = NULL;
+       cJSON *props_participant = NULL;
+
+       ks_assert(bm);
+       ks_assert(breq);
+
+       ks_log(KS_LOG_DEBUG, "Request Received!\n");
+
+       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
+       ks_assert(bm_chat);
+
+       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
+       ks_assert(bs);
+
+       // @todo properties only used to demonstrate a flexible container for session data, should just rely on the participants list/hash
+       blade_session_properties_write_lock(bs, KS_TRUE);
+
+       props = blade_session_properties_get(bs);
+       ks_assert(props);
+
+       props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
+       if (props_participant && props_participant->type == cJSON_True) {
+               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to join chat but is already a participant\n", blade_session_id_get(bs));
+               blade_rpc_error_create(&res, NULL, breq->message_id, -10000, "Already a participant of chat");
+       }
+       else {
+               ks_log(KS_LOG_DEBUG, "Session (%s) joined chat\n", blade_session_id_get(bs));
+
+               if (props_participant) props_participant->type = cJSON_True;
+               else cJSON_AddTrueToObject(props, "blade.chat.participant");
+
+               ks_list_append(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and cleanup when removed
+
+               blade_rpc_response_create(&res, NULL, breq->message_id);
+
+               // @todo create an event to send to participants when a session joins and leaves, send after main response though
+       }
+
+       blade_session_properties_write_unlock(bs);
+
+       blade_session_send(bs, res, NULL);
+
+       blade_session_read_unlock(bs);
+
+       cJSON_Delete(res);
+
+       return KS_FALSE;
+}
+
+ks_bool_t blade_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq)
+{
+       blade_module_chat_t *bm_chat = NULL;
+       blade_session_t *bs = NULL;
+       cJSON *res = NULL;
+       cJSON *props = NULL;
+       cJSON *props_participant = NULL;
+
+       ks_assert(bm);
+       ks_assert(breq);
+
+       ks_log(KS_LOG_DEBUG, "Request Received!\n");
+
+       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
+       ks_assert(bm_chat);
+
+       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
+       ks_assert(bs);
+
+       blade_session_properties_write_lock(bs, KS_TRUE);
+
+       props = blade_session_properties_get(bs);
+       ks_assert(props);
+
+       props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
+       if (!props_participant || props_participant->type == cJSON_False) {
+               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to leave chat but is not a participant\n", blade_session_id_get(bs));
+               blade_rpc_error_create(&res, NULL, breq->message_id, -10000, "Not a participant of chat");
+       }
+       else {
+               ks_log(KS_LOG_DEBUG, "Session (%s) left chat\n", blade_session_id_get(bs));
+
+               cJSON_DeleteItemFromObject(props, "blade.chat.participant");
+
+               ks_list_delete(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
+
+               blade_rpc_response_create(&res, NULL, breq->message_id);
+
+               // @todo create an event to send to participants when a session joins and leaves, send after main response though
+       }
+
+       blade_session_properties_write_unlock(bs);
+
+       blade_session_send(bs, res, NULL);
+
+       blade_session_read_unlock(bs);
+
+       cJSON_Delete(res);
+
+       return KS_FALSE;
+}
+
+ks_bool_t blade_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq)
+{
+       blade_module_chat_t *bm_chat = NULL;
+       blade_session_t *bs = NULL;
+       cJSON *params = NULL;
+       cJSON *res = NULL;
+       cJSON *event = NULL;
+       const char *message = NULL;
+       ks_bool_t sendevent = KS_FALSE;
+
+       ks_assert(bm);
+       ks_assert(breq);
+
+       ks_log(KS_LOG_DEBUG, "Request Received!\n");
+
+       bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
+       ks_assert(bm_chat);
+
+       params = cJSON_GetObjectItem(breq->message, "params"); // @todo cache this in blade_request_t for quicker/easier access
+       if (!params) {
+               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to send chat message with no 'params' object\n", blade_session_id_get(bs));
+               blade_rpc_error_create(&res, NULL, breq->message_id, -32602, "Missing params object");
+       }
+       else if (!(message = cJSON_GetObjectCstr(params, "message"))) {
+               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to send chat message with no 'message'\n", blade_session_id_get(bs));
+               blade_rpc_error_create(&res, NULL, breq->message_id, -32602, "Missing params message string");
+       }
+
+       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
+       ks_assert(bs);
+
+       if (!res) {
+               blade_rpc_response_create(&res, NULL, breq->message_id);
+               sendevent = KS_TRUE;
+       }
+       blade_session_send(bs, res, NULL);
+
+       blade_session_read_unlock(bs);
+
+       cJSON_Delete(res);
+
+       if (sendevent) {
+               blade_rpc_event_create(&event, &res, "blade.chat.message");
+               ks_assert(event);
+               cJSON_AddStringToObject(res, "from", breq->session_id); // @todo should really be the identity, but we don't have that in place yet
+               cJSON_AddStringToObject(res, "message", message);
+
+               blade_handle_sessions_send(breq->handle, bm_chat->participants, NULL, event);
+
+               cJSON_Delete(event);
+       }
+
+       return KS_FALSE;
+}
+
+
+/* For Emacs:
+* Local Variables:
+* mode:c
+* indent-tabs-mode:t
+* tab-width:4
+* c-basic-offset:4
+* End:
+* For VIM:
+* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
+*/
index ff6ee2ba1f71ba32355359f47bcb4ff9f4d2e601..33052e4e815121ff195ed3853f2380aec2b58996 100644 (file)
@@ -49,6 +49,7 @@ KS_BEGIN_EXTERN_C
 #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
 #define _WINSOCK_DEPRECATED_NO_WARNINGS
 #endif
+#define _CRTDBG_MAP_ALLOC
 #endif
 
 #ifndef _GNU_SOURCE
@@ -96,6 +97,7 @@ KS_BEGIN_EXTERN_C
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <windows.h>
+#include <crtdbg.h>
 #else
 #include <sys/time.h>
 #include <sys/select.h>
index 984d18461e9e7274a197ff0efa930bdf50aff068..6466b451955df7acfb3dd87ce5c611a428745954 100644 (file)
@@ -102,7 +102,11 @@ KS_DECLARE(void) ks_ssl_destroy_ssl_locks(void)
 
                OPENSSL_free(ssl_mutexes);
                ssl_count--;
+               if (ssl_pool) ks_pool_close(&ssl_pool);
        }
+
+       SSL_COMP_free_compression_methods();
+       EVP_cleanup();
 }
 
 
index a68280730dc8546f6720ad96a8d46554199afcf9..01d99e1fa0f76193c306d37f5203dd045ae0bec4 100644 (file)
@@ -128,7 +128,7 @@ static void *worker_thread(ks_thread_t *thread, void *data)
                void *pop = NULL;
                ks_status_t status;
                
-               status = ks_q_pop_timeout(tp->q, &pop, 1000);
+               status = ks_q_pop_timeout(tp->q, &pop, 100);
                if (status == KS_STATUS_BREAK) {
                        if (tp->state != TP_STATE_RUNNING) {
                                break;