[asterisk-commits] wedhorn: branch wedhorn/skinny-session r390739 - /team/wedhorn/skinny-session...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jun 6 16:00:36 CDT 2013
Author: wedhorn
Date: Thu Jun 6 16:00:34 2013
New Revision: 390739
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=390739
Log:
skinny: restructure skinny_session thread to be cancelled externally
Modified:
team/wedhorn/skinny-session/channels/chan_skinny.c
Modified: team/wedhorn/skinny-session/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/skinny-session/channels/chan_skinny.c?view=diff&rev=390739&r1=390738&r2=390739
==============================================================================
--- team/wedhorn/skinny-session/channels/chan_skinny.c (original)
+++ team/wedhorn/skinny-session/channels/chan_skinny.c Thu Jun 6 16:00:34 2013
@@ -2302,34 +2302,9 @@
return 1;
}
-static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
-{
- struct skinny_device *d;
- struct skinny_line *l;
- struct skinny_speeddial *sd;
-
- d = s->device;
-
- if (d) {
- d->session = NULL;
-
- AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
- if (sd->stateid > -1)
- ast_extension_state_del(sd->stateid, NULL);
- }
- AST_LIST_TRAVERSE(&d->lines, l, list) {
- if (l->device == d) {
- ast_format_cap_remove_all(l->cap);
- ast_parse_allow_disallow(&l->prefs, l->cap, "all", 0);
- l->instance = 0;
- manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
- unregister_exten(l);
- ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
- }
- }
- }
-
- return -1; /* main loop will destroy the session */
+static void end_session(struct skinnysession *s)
+{
+ pthread_cancel(s->t);
}
#ifdef AST_DEVMODE
@@ -2395,7 +2370,7 @@
ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));
if (res == -1) {
ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n");
- skinny_unregister(NULL, s);
+ end_session(s);
}
}
@@ -7322,7 +7297,7 @@
break;
case UNREGISTER_MESSAGE:
SKINNY_DEBUG(DEBUG_PACKET, 3, "Received UNREGISTER_MESSAGE from %s\n", d->name);
- res = skinny_unregister(req, s);
+ end_session(s);
break;
case SOFT_KEY_TEMPLATE_REQ_MESSAGE:
SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFT_KEY_TEMPLATE_REQ_MESSAGE from %s\n", d->name);
@@ -7349,36 +7324,18 @@
static void destroy_session(struct skinnysession *s)
{
- struct skinnysession *cur;
- AST_LIST_LOCK(&sessions);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, cur, list) {
- if (cur == s) {
- AST_LIST_REMOVE_CURRENT(list);
- if (s->fd > -1) {
- close(s->fd);
- }
-
- if (s->device) {
- s->device->session = NULL;
- } else {
- ast_atomic_fetchadd_int(&unauth_sessions, -1);
- }
-
- ast_mutex_destroy(&s->lock);
-
- ast_free(s);
-
- break;
- }
- }
- AST_LIST_TRAVERSE_SAFE_END
- AST_LIST_UNLOCK(&sessions);
-}
-
-static void end_session(struct skinnysession *s)
-{
- s->destroy = 1;
- pthread_kill(s->t, SIGURG);
+ if (s->fd > -1) {
+ close(s->fd);
+ }
+
+ if (s->device) {
+ s->device->session = NULL;
+ } else {
+ ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ }
+
+ ast_mutex_destroy(&s->lock);
+ ast_free(s);
}
static int skinny_noauth_cb(const void *data)
@@ -7388,6 +7345,42 @@
s->auth_timeout_sched = 0;
end_session(s);
return 0;
+}
+
+static void skinny_session_cleanup(void *data)
+{
+ struct skinnysession *s = (struct skinnysession *)data;
+ struct skinny_device *d = s->device;
+ struct skinny_line *l;
+ struct skinny_speeddial *sd;
+
+ ast_verb(3, "Ending Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr));
+
+ if (d) {
+ d->session = NULL;
+
+ AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
+ if (sd->stateid > -1)
+ ast_extension_state_del(sd->stateid, NULL);
+ }
+ AST_LIST_TRAVERSE(&d->lines, l, list) {
+ if (l->device == d) {
+ ast_format_cap_remove_all(l->cap);
+ ast_parse_allow_disallow(&l->prefs, l->cap, "all", 0);
+ l->instance = 0;
+ manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
+ unregister_exten(l);
+ ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "Skinny/%s", l->name);
+ }
+ }
+ }
+
+ destroy_session(s);
+
+ AST_LIST_LOCK(&sessions);
+ AST_LIST_REMOVE(&sessions, s, list);
+ AST_LIST_UNLOCK(&sessions);
+
}
static void *skinny_session(void *data)
@@ -7407,7 +7400,19 @@
}
ast_verb(3, "Starting Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr));
- s->destroy = 0;
+
+ pthread_cleanup_push(skinny_session_cleanup, s);
+
+ if(time(&s->start) == -1) {
+ ast_log(LOG_ERROR, "error executing time(): %s; continuing without start time\n", strerror(errno));
+ }
+
+ ast_mutex_init(&s->lock);
+
+ AST_LIST_LOCK(&sessions);
+ AST_LIST_INSERT_HEAD(&sessions, s, list);
+ AST_LIST_UNLOCK(&sessions);
+
s->auth_timeout_sched = ast_sched_add(sched, auth_timeout*1000, skinny_noauth_cb, s);
for (;;) {
@@ -7501,7 +7506,9 @@
ast_mutex_unlock(&s->lock);
lockstate = 0;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
res = handle_message(req, s);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (res < 0) {
ast_verb(3, "Ending Skinny session from %s\n", ast_inet_ntoa(s->sin.sin_addr));
break;
@@ -7521,8 +7528,8 @@
if (req) {
ast_free(req);
}
- skinny_unregister(NULL, s);
- destroy_session(s);
+
+ pthread_cleanup_pop(1);
return 0;
}
@@ -7563,18 +7570,7 @@
}
memcpy(&s->sin, &sin, sizeof(sin));
- ast_mutex_init(&s->lock);
s->fd = as;
-
- if(time(&s->start) == -1) {
- ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
- destroy_session(s);
- continue;
- }
-
- AST_LIST_LOCK(&sessions);
- AST_LIST_INSERT_HEAD(&sessions, s, list);
- AST_LIST_UNLOCK(&sessions);
if (ast_pthread_create(&s->t, NULL, skinny_session, s)) {
destroy_session(s);
@@ -8625,6 +8621,7 @@
struct skinny_line *l;
struct skinny_subchannel *sub;
struct ast_context *con;
+ int tempthread;
ast_rtp_glue_unregister(&skinny_rtp_glue);
ast_channel_unregister(&skinny_tech);
@@ -8635,9 +8632,19 @@
ast_manager_unregister("SKINNYlines");
ast_manager_unregister("SKINNYshowline");
+ ast_mutex_lock(&netlock);
+ if (accept_t && (accept_t != AST_PTHREADT_STOP)) {
+ pthread_cancel(accept_t);
+ pthread_kill(accept_t, SIGURG);
+ pthread_join(accept_t, NULL);
+ }
+ accept_t = AST_PTHREADT_STOP;
+ ast_mutex_unlock(&netlock);
+
AST_LIST_LOCK(&sessions);
/* Destroy all the interfaces and free their memory */
while((s = AST_LIST_REMOVE_HEAD(&sessions, list))) {
+ AST_LIST_UNLOCK(&sessions);
d = s->device;
AST_LIST_TRAVERSE(&d->lines, l, list){
ast_mutex_lock(&l->lock);
@@ -8655,25 +8662,14 @@
manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
unregister_exten(l);
}
- if (s->fd > -1)
- close(s->fd);
- pthread_cancel(s->t);
- pthread_kill(s->t, SIGURG);
- pthread_join(s->t, NULL);
- free(s);
+ tempthread = s->t;
+ pthread_cancel(tempthread);
+ pthread_join(tempthread, NULL);
+ AST_LIST_LOCK(&sessions);
}
AST_LIST_UNLOCK(&sessions);
delete_devices();
-
- ast_mutex_lock(&netlock);
- if (accept_t && (accept_t != AST_PTHREADT_STOP)) {
- pthread_cancel(accept_t);
- pthread_kill(accept_t, SIGURG);
- pthread_join(accept_t, NULL);
- }
- accept_t = AST_PTHREADT_STOP;
- ast_mutex_unlock(&netlock);
close(skinnysock);
if (sched) {
More information about the asterisk-commits
mailing list