提交 04005dfa authored 作者: Peter Olsson's avatar Peter Olsson

mod_v8: Added new extension class that makes it possible to subscribe to FS…

mod_v8: Added new extension class that makes it possible to subscribe to FS events. Wiki will be updated soon.
上级 ab2bc7c6
......@@ -90,7 +90,8 @@ mod_v8_la_SOURCES = \
src/fssocket.cpp \
src/fsteletone.cpp \
src/fsxml.cpp \
src/fsfile.cpp
src/fsfile.cpp \
src/fseventhandler.cpp
mod_v8_la_CFLAGS = $(AM_CFLAGS) $(LIBCURL_CPPFLAGS) -I$(switch_srcdir)/libs/libteletone/src
mod_v8_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCURL_CPPFLAGS) -I$(switch_srcdir)/libs/libteletone/src
......
/*
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Peter Olsson <peter@olssononline.se>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Olsson <peter@olssononline.se>
*
* fseventhandler.hpp -- JavaScript EventHandler class header
*
*/
#ifndef FS_EVENTHANDLER_H
#define FS_EVENTHANDLER_H
#include "mod_v8.h"
/* Macros for easier V8 callback definitions */
#define JS_EVENTHANDLER_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSEventHandler)
#define JS_EVENTHANDLER_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSEventHandler)
#define JS_EVENTHANDLER_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSEventHandler)
#define JS_EVENTHANDLER_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSEventHandler)
#define JS_EVENTHANDLER_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSEventHandler)
#define JS_EVENTHANDLER_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSEventHandler)
#define JS_EVENTHANDLER_FUNCTION_IMPL_STATIC(method_name) JS_FUNCTION_IMPL_STATIC(method_name, FSEventHandler)
#define JS_EVENTHANDLER_GET_PROPERTY_IMPL_STATIC(method_name) JS_GET_PROPERTY_IMPL_STATIC(method_name, FSEventHandler)
class FSEventHandler : public JSBase
{
private:
switch_mutex_t *_mutex;
switch_memory_pool_t *_pool;
switch_hash_t *_event_hash;
switch_queue_t *_event_queue;
uint8_t _event_list[SWITCH_EVENT_ALL + 1];
switch_event_t *_filters;
void Init();
void DoSubscribe(const v8::FunctionCallbackInfo<v8::Value>& info);
public:
FSEventHandler(JSMain *owner) : JSBase(owner) { Init(); }
FSEventHandler(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
virtual ~FSEventHandler(void);
virtual std::string GetJSClassName();
static const v8_mod_interface_t *GetModuleInterface();
/* Public method to queue an event to this instance */
void QueueEvent(switch_event_t *event);
/* Methods available from JavaScript */
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
JS_EVENTHANDLER_FUNCTION_DEF(Subscribe);
JS_EVENTHANDLER_FUNCTION_DEF(UnSubscribe);
JS_EVENTHANDLER_FUNCTION_DEF(AddFilter);
JS_EVENTHANDLER_FUNCTION_DEF(DeleteFilter);
JS_EVENTHANDLER_FUNCTION_DEF(GetEvent);
JS_EVENTHANDLER_FUNCTION_DEF(SendEvent);
JS_EVENTHANDLER_FUNCTION_DEF(ExecuteApi);
JS_EVENTHANDLER_FUNCTION_DEF(ExecuteBgApi);
JS_FUNCTION_DEF_STATIC(Destroy);
JS_GET_PROPERTY_DEF_STATIC(GetReadyProperty);
};
#endif /* FS_EVENTHANDLER_H */
/* 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:
*/
......@@ -178,6 +178,7 @@
<ClCompile Include=".\src\fsglobal.cpp" />
<ClCompile Include=".\src\fsteletone.cpp" />
<ClCompile Include="mod_v8.cpp" />
<ClCompile Include="src\fseventhandler.cpp" />
<ClCompile Include="src\fsfile.cpp" />
<ClCompile Include="src\fsxml.cpp" />
</ItemGroup>
......@@ -195,6 +196,7 @@
<ClInclude Include=".\include\fssocket.hpp" />
<ClInclude Include=".\include\fsglobal.hpp" />
<ClInclude Include=".\include\fsteletone.hpp" />
<ClInclude Include="include\fseventhandler.hpp" />
<ClInclude Include="include\fsfile.hpp" />
<ClInclude Include="include\fsxml.hpp" />
<ClInclude Include="mod_v8.h" />
......
......@@ -50,6 +50,9 @@
<ClCompile Include="src\fsxml.cpp">
<Filter>FSClasses</Filter>
</ClCompile>
<ClCompile Include="src\fseventhandler.cpp">
<Filter>FSClasses</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mod_v8.h" />
......@@ -98,6 +101,9 @@
<ClInclude Include="include\fsxml.hpp">
<Filter>FSClasses\include</Filter>
</ClInclude>
<ClInclude Include="include\fseventhandler.hpp">
<Filter>FSClasses\include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="BaseClasses">
......
......@@ -182,6 +182,7 @@
<ClCompile Include=".\src\fsglobal.cpp" />
<ClCompile Include=".\src\fsteletone.cpp" />
<ClCompile Include="mod_v8.cpp" />
<ClCompile Include="src\fseventhandler.cpp" />
<ClCompile Include="src\fsfile.cpp" />
<ClCompile Include="src\fsxml.cpp" />
</ItemGroup>
......@@ -199,6 +200,7 @@
<ClInclude Include=".\include\fssocket.hpp" />
<ClInclude Include=".\include\fsglobal.hpp" />
<ClInclude Include=".\include\fsteletone.hpp" />
<ClInclude Include="include\fseventhandler.hpp" />
<ClInclude Include="include\fsfile.hpp" />
<ClInclude Include="include\fsxml.hpp" />
<ClInclude Include="mod_v8.h" />
......
......@@ -50,6 +50,9 @@
<ClCompile Include="src\fsxml.cpp">
<Filter>FSClasses</Filter>
</ClCompile>
<ClCompile Include="src\fseventhandler.cpp">
<Filter>FSClasses</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mod_v8.h" />
......@@ -98,6 +101,9 @@
<ClInclude Include="include\fsxml.hpp">
<Filter>FSClasses\include</Filter>
</ClInclude>
<ClInclude Include="include\fseventhandler.hpp">
<Filter>FSClasses\include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="BaseClasses">
......
......@@ -38,6 +38,7 @@
* CURL Adds some extra methods for CURL access. (on request only)
* DTMF Object that holds information about a DTMF event.
* Event Object that holds information about a FreeSWITCH event.
* EventHandler Features for handling FS events.
* File Class to reflect the Spidermonkey built-in class "File". Not yet implemented! (on request only)
* FileIO Simple class for basic file IO.
* ODBC Adds features to access any ODBC available database in the system. (on request only)
......@@ -73,7 +74,7 @@
#include "fsglobal.hpp"
/* Common JavaScript classes */
#include "fsrequest.hpp" /* Only loaded during 'jsapi' call */
#include "fsrequest.hpp" /* Only loaded during 'jsapi' and 'jsjson' call */
#include "fspcre.hpp"
#include "fsevent.hpp"
#include "fssession.hpp"
......@@ -88,6 +89,9 @@
#include "fsodbc.hpp"
#include "fsxml.hpp"
#include "fsfile.hpp"
#include "fseventhandler.hpp"
#include <set>
using namespace std;
using namespace v8;
......@@ -106,7 +110,17 @@ static switch_api_interface_t *jsapi_interface = NULL;
/* Module manager for loadable modules */
module_manager_t module_manager = { 0 };
/* Loadable module struct */
/* Global data for this module */
typedef struct {
switch_memory_pool_t *pool;
switch_mutex_t *event_mutex;
switch_event_node_t *event_node;
set<FSEventHandler *> *event_handlers;
} mod_v8_global_t;
mod_v8_global_t globals = { 0 };
/* Loadable module struct, used for external extension modules */
typedef struct {
char *filename;
void *lib;
......@@ -258,7 +272,6 @@ static switch_status_t load_modules(void)
const char *EXT = ".SO";
#endif
memset(&module_manager, 0, sizeof(module_manager));
switch_core_new_memory_pool(&module_manager.pool);
switch_core_hash_init(&module_manager.load_hash, module_manager.pool);
......@@ -688,8 +701,53 @@ static void v8_thread_launch(const char *text)
switch_thread_create(&thread, thd_attr, v8_thread_run, task, pool);
}
void v8_add_event_handler(void *event_handler)
{
FSEventHandler *eh = static_cast<FSEventHandler *>(event_handler);
if (eh) {
switch_mutex_lock(globals.event_mutex);
globals.event_handlers->insert(eh);
switch_mutex_unlock(globals.event_mutex);
}
}
void v8_remove_event_handler(void *event_handler)
{
FSEventHandler *eh = static_cast<FSEventHandler *>(event_handler);
if (eh) {
switch_mutex_lock(globals.event_mutex);
set<FSEventHandler *>::iterator it = globals.event_handlers->find(eh);
if (it != globals.event_handlers->end()) {
globals.event_handlers->erase(it);
}
switch_mutex_unlock(globals.event_mutex);
}
}
SWITCH_BEGIN_EXTERN_C
static void event_handler(switch_event_t *event)
{
if (event) {
switch_mutex_lock(globals.event_mutex);
set<FSEventHandler *>::iterator it;
for (it = globals.event_handlers->begin(); it != globals.event_handlers->end(); ++it) {
if (*it) {
(*it)->QueueEvent(event);
}
}
switch_mutex_unlock(globals.event_mutex);
}
}
SWITCH_STANDARD_API(jsapi_function)
{
char *path_info = NULL;
......@@ -769,6 +827,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_v8_load)
switch_chat_application_interface_t *chat_app_interface;
switch_json_api_interface_t *json_api_interface;
if (switch_event_bind_removable(modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.event_node) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind to events\n");
return SWITCH_STATUS_GENERR;
}
if (switch_core_new_memory_pool(&globals.pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n");
return SWITCH_STATUS_GENERR;
}
switch_mutex_init(&globals.event_mutex, SWITCH_MUTEX_NESTED, globals.pool);
globals.event_handlers = new set<FSEventHandler *>();
if (load_modules() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
}
......@@ -786,6 +857,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_v8_load)
v8_mod_init_built_in(FSTeleTone::GetModuleInterface());
v8_mod_init_built_in(FSXML::GetModuleInterface());
v8_mod_init_built_in(FSFile::GetModuleInterface());
v8_mod_init_built_in(FSEventHandler::GetModuleInterface());
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
......@@ -802,6 +874,12 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_v8_load)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_v8_shutdown)
{
switch_event_unbind(&globals.event_node);
delete globals.event_handlers;
switch_mutex_destroy(globals.event_mutex);
switch_core_destroy_memory_pool(&globals.pool);
switch_core_hash_destroy(&module_manager.load_hash);
return SWITCH_STATUS_SUCCESS;
......
......@@ -40,15 +40,19 @@ SWITCH_BEGIN_EXTERN_C
#define JS_BUFFER_SIZE 1024 * 32
#define JS_BLOCK_SIZE JS_BUFFER_SIZE
/* Function definition for initialization of an extension module */
typedef switch_status_t (*v8_mod_load_t) (const v8::FunctionCallbackInfo<v8::Value>& info);
/* Extension module interface, stored inside the load_hash */
typedef struct {
const char *name;
v8_mod_load_t v8_mod_load;
} v8_mod_interface_t;
/* Function definition for external extension module */
typedef switch_status_t (*v8_mod_init_t) (const v8_mod_interface_t **module_interface);
/* Struct that holds information about loadable extension modules */
typedef struct {
switch_hash_t *load_hash;
switch_memory_pool_t *pool;
......@@ -58,6 +62,9 @@ extern module_manager_t module_manager;
SWITCH_END_EXTERN_C
void v8_add_event_handler(void *event_handler);
void v8_remove_event_handler(void *event_handler);
#endif /* MOD_V8_H */
/* For Emacs:
......
......@@ -69,7 +69,7 @@ JSBase::~JSBase(void)
}
/* If the object is still alive inside V8, set the internal field to NULL. But only if we're actually inside a JS context */
if (!persistentHandle->IsNearDeath() && !GetIsolate()->GetCurrentContext().IsEmpty()) {
if (!persistentHandle->IsNearDeath() && !GetIsolate()->GetCurrentContext().IsEmpty() && (!js || !js->GetForcedTermination())) {
Handle<Object> jsObj = GetJavaScriptObject();
jsObj->SetInternalField(0, Null(GetIsolate()));
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论