skypopen: fixed management of skype clients crash
This commit is contained in:
parent
38215f9d5c
commit
182da3c128
|
@ -174,6 +174,7 @@ int running = 0;
|
|||
struct SkypopenList global_handles_list;
|
||||
extern int xio_error_handler(Display * dpy);
|
||||
extern int X11_errors_handler(Display * dpy, XErrorEvent * err);
|
||||
extern int xio_error_handler2(Display * dpy, XErrorEvent * err);
|
||||
#endif
|
||||
|
||||
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context);
|
||||
|
@ -357,6 +358,8 @@ static switch_status_t interface_exists(char *the_interface)
|
|||
|
||||
globals.SKYPOPEN_INTERFACES[interface_id].running = 0;
|
||||
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_DEAD;
|
||||
|
||||
if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread) {
|
||||
#ifdef WIN32
|
||||
skypopen_signaling_write(tech_pvt, "DIE");
|
||||
|
@ -377,8 +380,8 @@ static switch_status_t interface_exists(char *the_interface)
|
|||
if (tech_pvt->running && tech_pvt->SkypopenHandles.disp) {
|
||||
XEvent e;
|
||||
Atom atom1 = XInternAtom(tech_pvt->SkypopenHandles.disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False);
|
||||
switch_sleep(1000); //giovanni
|
||||
XFlush(tech_pvt->SkypopenHandles.disp); //giovanni
|
||||
switch_sleep(1000);
|
||||
XFlush(tech_pvt->SkypopenHandles.disp);
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.xclient.type = ClientMessage;
|
||||
e.xclient.message_type = atom1; /* leading message */
|
||||
|
@ -387,7 +390,7 @@ static switch_status_t interface_exists(char *the_interface)
|
|||
e.xclient.format = 8;
|
||||
|
||||
XSendEvent(tech_pvt->SkypopenHandles.disp, tech_pvt->SkypopenHandles.win, False, 0, &e);
|
||||
XFlush(tech_pvt->SkypopenHandles.disp); //giovanni
|
||||
XFlush(tech_pvt->SkypopenHandles.disp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -399,9 +402,6 @@ static switch_status_t interface_exists(char *the_interface)
|
|||
|
||||
#ifndef WIN32
|
||||
if (tech_pvt->SkypopenHandles.disp) {
|
||||
DEBUGA_SKYPE("REMOVE CLOSIN X\n", SKYPOPEN_P_LOG);
|
||||
XCloseDisplay(tech_pvt->SkypopenHandles.disp);
|
||||
DEBUGA_SKYPE("REMOVE CLOSIN X END\n", SKYPOPEN_P_LOG);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -420,7 +420,11 @@ static switch_status_t interface_exists(char *the_interface)
|
|||
} else {
|
||||
DEBUGA_SKYPE("interface '%s' STILL console\n", SKYPOPEN_P_LOG, the_interface);
|
||||
}
|
||||
memset(&globals.SKYPOPEN_INTERFACES[interface_id], '\0', sizeof(private_t));
|
||||
if(strlen(tech_pvt->session_uuid_str)){
|
||||
|
||||
}else{
|
||||
memset(&globals.SKYPOPEN_INTERFACES[interface_id], '\0', sizeof(private_t));
|
||||
}
|
||||
globals.real_interfaces--;
|
||||
switch_mutex_unlock(globals.mutex);
|
||||
|
||||
|
@ -473,7 +477,9 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
|
|||
if (tech_pvt) {
|
||||
DEBUGA_SKYPE("%s CHANNEL DESTROY %s\n", SKYPOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session));
|
||||
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_DOWN;
|
||||
if (tech_pvt->interface_state != SKYPOPEN_STATE_DEAD) {
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_DOWN;
|
||||
}
|
||||
|
||||
switch_mutex_lock(tech_pvt->flag_mutex);
|
||||
switch_clear_flag(tech_pvt, TFLAG_IO);
|
||||
|
@ -553,13 +559,13 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session)
|
|||
//DEBUGA_SKYPE("debugging_hangup 18\n", SKYPOPEN_P_LOG);
|
||||
|
||||
*tech_pvt->session_uuid_str = '\0';
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_IDLE;
|
||||
tech_pvt->skype_callflow = CALLFLOW_CALL_IDLE;
|
||||
#if 0
|
||||
if (tech_pvt->skype_callflow == CALLFLOW_STATUS_FINISHED) {
|
||||
|
||||
if (tech_pvt->interface_state != SKYPOPEN_STATE_DEAD) {
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_IDLE;
|
||||
tech_pvt->skype_callflow = CALLFLOW_CALL_IDLE;
|
||||
}else{
|
||||
memset(tech_pvt, '\0', sizeof(private_t));
|
||||
}
|
||||
#endif //
|
||||
switch_core_session_set_private(session, NULL);
|
||||
} else {
|
||||
DEBUGA_SKYPE("!!!!!!NO tech_pvt!!!! CHANNEL DESTROY %s\n", SKYPOPEN_P_LOG, switch_core_session_get_uuid(session));
|
||||
|
@ -585,6 +591,9 @@ static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
|||
//DEBUGA_SKYPE("debugging_hangup 1\n", SKYPOPEN_P_LOG);
|
||||
|
||||
if (tech_pvt) {
|
||||
if (tech_pvt->interface_state == SKYPOPEN_STATE_DEAD) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
if (!switch_channel_test_flag(channel, CF_ANSWERED)) {
|
||||
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||
tech_pvt->ob_failed_calls++;
|
||||
|
@ -684,6 +693,10 @@ static switch_status_t channel_kill_channel(switch_core_session_t *session, int
|
|||
switch (sig) {
|
||||
case SWITCH_SIG_KILL:
|
||||
DEBUGA_SKYPE("%s CHANNEL got SWITCH_SIG_KILL\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel));
|
||||
if (tech_pvt->interface_state == SKYPOPEN_STATE_DEAD) {
|
||||
switch_channel_set_state(channel, CS_HANGUP);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_HANGUP_REQUESTED;
|
||||
if (tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD) {
|
||||
DEBUGA_SKYPE("FYI %s CHANNEL in CALLFLOW_STATUS_REMOTEHOLD got SWITCH_SIG_KILL\n", SKYPOPEN_P_LOG, switch_channel_get_name(channel));
|
||||
|
@ -1387,6 +1400,9 @@ static void *SWITCH_THREAD_FUNC skypopen_signaling_thread_func(switch_thread_t *
|
|||
DEBUGA_SKYPE("skype call ended\n", SKYPOPEN_P_LOG);
|
||||
|
||||
if (tech_pvt) {
|
||||
if (tech_pvt->interface_state == SKYPOPEN_STATE_DEAD) {
|
||||
break;
|
||||
}
|
||||
session = switch_core_session_locate(tech_pvt->session_uuid_str);
|
||||
if (session) {
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
@ -1935,28 +1951,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skypopen_load)
|
|||
// CLOUDTREE (Thomas Hazel)
|
||||
#ifndef WIN32
|
||||
// XXX: these assumes no one will override
|
||||
XSetErrorHandler(X11_errors_handler);
|
||||
//XSetErrorHandler(X11_errors_handler);
|
||||
//XXX giovanni: seems that if Xserver is up, but skype client is crashed, the error is non fatal. Let's use Thomas handler in this case too
|
||||
XSetErrorHandler(xio_error_handler2);
|
||||
XSetIOErrorHandler(xio_error_handler);
|
||||
|
||||
memset(&global_handles_list, 0, sizeof(global_handles_list));
|
||||
switch_mutex_init(&globals.list_mutex, SWITCH_MUTEX_NESTED, skypopen_module_pool);
|
||||
#endif
|
||||
|
||||
// CLOUDTREE (Thomas Hazel) - load_configs no longer locks things up, no need to fail load
|
||||
load_config(FULL_RELOAD);
|
||||
|
||||
// CLOUDTREE (Thomas Hazel) - setting "running = 1;" use to be located before "load_config"
|
||||
running = 1;
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_INCOMING_CHATMESSAGE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_INCOMING_RAW) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
load_config(FULL_RELOAD);
|
||||
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
skypopen_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
|
||||
|
@ -1968,14 +1973,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skypopen_load)
|
|||
|
||||
SWITCH_ADD_API(commands_api_interface, "sk", "Skypopen console commands", sk_function, SK_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "skypopen", "Skypopen interface commands", skypopen_function, SKYPOPEN_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "skypopen_chat", "Skypopen_chat interface remote_skypename TEXT", skypopen_chat_function,
|
||||
SKYPOPEN_CHAT_SYNTAX);
|
||||
SWITCH_ADD_API(commands_api_interface, "skypopen_chat", "Skypopen_chat interface remote_skypename TEXT", skypopen_chat_function, SKYPOPEN_CHAT_SYNTAX);
|
||||
SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send);
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_INCOMING_CHATMESSAGE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_INCOMING_RAW) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
} else
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypopen_shutdown)
|
||||
|
|
|
@ -132,6 +132,7 @@ typedef enum {
|
|||
#define SKYPOPEN_STATE_SELECTED 9
|
||||
#define SKYPOPEN_STATE_HANGUP_REQUESTED 10
|
||||
#define SKYPOPEN_STATE_PREANSWER 11
|
||||
#define SKYPOPEN_STATE_DEAD 99
|
||||
/*********************************/
|
||||
/* call flow from the device */
|
||||
#define CALLFLOW_CALL_IDLE 0
|
||||
|
|
|
@ -1514,6 +1514,30 @@ int xio_error_handler(Display * dpy)
|
|||
|
||||
return 0;
|
||||
}
|
||||
int xio_error_handler2(Display * dpy, XErrorEvent * err)
|
||||
{
|
||||
private_t *tech_pvt = NULL;
|
||||
struct SkypopenHandles *handle;
|
||||
global_x_error = err->error_code;
|
||||
|
||||
ERRORA("Received error code %d from X Server\n\n", SKYPOPEN_P_LOG, global_x_error);
|
||||
ERRORA("Display error for %d, %s\n", SKYPOPEN_P_LOG, skypopen_list_size(&global_handles_list), dpy->display_name);
|
||||
|
||||
handle = skypopen_list_remove_by_value(&global_handles_list, dpy);
|
||||
if (handle != NULL) {
|
||||
#ifdef XIO_ERROR_BY_SETJMP
|
||||
siglongjmp(handle->ioerror_context, 1);
|
||||
#endif
|
||||
#ifdef XIO_ERROR_BY_UCONTEXT
|
||||
setcontext(&handle->ioerror_context);
|
||||
#endif
|
||||
}
|
||||
|
||||
ERRORA("Fatal display error for %p, %s - failed to siglongjmp\n", SKYPOPEN_P_LOG, (void *) handle, dpy->display_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int X11_errors_handler(Display * dpy, XErrorEvent * err)
|
||||
{
|
||||
|
@ -1685,25 +1709,38 @@ void *skypopen_do_skypeapi_thread_func(void *obj)
|
|||
// CLOUDTREE (Thomas Hazel)
|
||||
#ifndef WIN32
|
||||
{
|
||||
char interfacename[256];
|
||||
|
||||
skypopen_list_add(&global_handles_list, SkypopenHandles);
|
||||
sprintf(interfacename, "#%s", tech_pvt->name);
|
||||
|
||||
#ifdef XIO_ERROR_BY_SETJMP
|
||||
if (sigsetjmp(SkypopenHandles->ioerror_context, 1) != 0) {
|
||||
switch_core_session_t *session = NULL;
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_DEAD;
|
||||
ERRORA("Fatal display error for %s - successed to jump\n", SKYPOPEN_P_LOG, tech_pvt->X11_display);
|
||||
|
||||
session = switch_core_session_locate(tech_pvt->session_uuid_str);
|
||||
if (session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
WARNINGA("Closing session %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_CRASH);
|
||||
|
||||
|
||||
switch_mutex_lock(tech_pvt->flag_mutex);
|
||||
switch_clear_flag(tech_pvt, TFLAG_IO);
|
||||
switch_clear_flag(tech_pvt, TFLAG_VOICE);
|
||||
if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) {
|
||||
switch_clear_flag(tech_pvt, TFLAG_PROGRESS);
|
||||
}
|
||||
switch_mutex_unlock(tech_pvt->flag_mutex);
|
||||
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_CRASH);
|
||||
}
|
||||
|
||||
WARNINGA("Removing skype user %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
|
||||
tech_pvt->skypopen_api_thread = NULL;
|
||||
remove_interface(tech_pvt->skype_user, TRUE);
|
||||
XCloseDisplay(disp);
|
||||
WARNINGA("Removing skype interface %s\n", SKYPOPEN_P_LOG, interfacename);
|
||||
remove_interface(interfacename, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
@ -1712,20 +1749,34 @@ void *skypopen_do_skypeapi_thread_func(void *obj)
|
|||
|
||||
if (skypopen_list_find(&global_handles_list, SkypopenHandles) == NULL) {
|
||||
switch_core_session_t *session = NULL;
|
||||
tech_pvt->interface_state = SKYPOPEN_STATE_DEAD;
|
||||
ERRORA("Fatal display error for %s - successed to jump\n", SKYPOPEN_P_LOG, tech_pvt->X11_display);
|
||||
|
||||
session = switch_core_session_locate(tech_pvt->session_uuid_str);
|
||||
if (session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
WARNINGA("Closing session %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_CRASH);
|
||||
|
||||
|
||||
switch_mutex_lock(tech_pvt->flag_mutex);
|
||||
switch_clear_flag(tech_pvt, TFLAG_IO);
|
||||
switch_clear_flag(tech_pvt, TFLAG_VOICE);
|
||||
if (switch_test_flag(tech_pvt, TFLAG_PROGRESS)) {
|
||||
switch_clear_flag(tech_pvt, TFLAG_PROGRESS);
|
||||
}
|
||||
switch_mutex_unlock(tech_pvt->flag_mutex);
|
||||
|
||||
|
||||
switch_core_session_rwunlock(session);
|
||||
WARNINGA("Closing session for %s\n", SKYPOPEN_P_LOG, interfacename);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_CRASH);
|
||||
|
||||
//skypopen_sleep(500000);
|
||||
}
|
||||
|
||||
WARNINGA("Removing skype user %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
|
||||
tech_pvt->skypopen_api_thread = NULL;
|
||||
remove_interface(tech_pvt->skype_user, TRUE);
|
||||
XCloseDisplay(disp);
|
||||
WARNINGA("Removing skype interface %s\n", SKYPOPEN_P_LOG, interfacename);
|
||||
//tech_pvt->skypopen_api_thread = NULL;
|
||||
remove_interface(interfacename, TRUE);
|
||||
//XCloseDisplay(disp);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue