Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
A
asterisk
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Voice
asterisk
Commits
1be506d8
Commit
1be506d8
authored
9 years ago
by
Joshua Colp
Committed by
Gerrit Code Review
9 years ago
Browse files
Options
Downloads
Plain Diff
Merge "res_pjsip_outbound_publish: state potential dropped on reloads/realtime fetches"
parents
086e311a
64e058f7
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
res/res_pjsip_outbound_publish.c
+117
-36
117 additions, 36 deletions
res/res_pjsip_outbound_publish.c
with
117 additions
and
36 deletions
res/res_pjsip_outbound_publish.c
+
117
−
36
View file @
1be506d8
...
...
@@ -406,22 +406,30 @@ static void sip_outbound_publish_synchronize(struct ast_sip_event_publisher_hand
ao2_ref
(
states
,
-
1
);
}
struct
ast_sip_outbound_publish_
client
*
ast_
sip_publish_
client
_get
(
const
char
*
name
)
static
struct
ast_sip_outbound_publish_
state
*
sip_publish_
state
_get
(
const
char
*
id
)
{
RAII_VAR
(
struct
ao2_container
*
,
states
,
ao2_global_obj_ref
(
current_states
),
ao2_cleanup
);
RAII_VAR
(
struct
ast_sip_outbound_publish_state
*
,
state
,
NULL
,
ao2_cleanup
);
struct
ao2_container
*
states
=
ao2_global_obj_ref
(
current_states
);
struct
ast_sip_outbound_publish_state
*
res
;
if
(
!
states
)
{
return
NULL
;
}
state
=
ao2_find
(
states
,
name
,
OBJ_SEARCH_KEY
);
res
=
ao2_find
(
states
,
id
,
OBJ_SEARCH_KEY
);
ao2_ref
(
states
,
-
1
);
return
res
;
}
struct
ast_sip_outbound_publish_client
*
ast_sip_publish_client_get
(
const
char
*
name
)
{
struct
ast_sip_outbound_publish_state
*
state
=
sip_publish_state_get
(
name
);
if
(
!
state
)
{
return
NULL
;
}
ao2_ref
(
state
->
client
,
+
1
);
ao2_ref
(
state
,
-
1
);
return
state
->
client
;
}
...
...
@@ -1086,25 +1094,89 @@ static struct ast_sip_outbound_publish_state *sip_outbound_publish_state_alloc(
return
state
;
}
/*! \brief Apply function which finds or allocates
a
st
ate structure */
static
int
sip_outbound_publish_
apply
(
const
struct
ast_sorcery
*
sorcery
,
void
*
obj
)
static
int
initialize_publish_client
(
struct
ast
_sip_outbound_publish
*
publish
,
struct
ast_
sip_outbound_publish_
state
*
state
)
{
RAII_VAR
(
struct
ao2_container
*
,
states
,
ao2_global_obj_ref
(
current_states
),
ao2_cleanup
);
RAII_VAR
(
struct
ast_sip_outbound_publish_state
*
,
state
,
NULL
,
ao2_cleanup
);
struct
ast_sip_outbound_publish
*
applied
=
obj
;
if
(
ast_sip_push_task_synchronous
(
NULL
,
sip_outbound_publish_client_alloc
,
state
->
client
))
{
ast_log
(
LOG_ERROR
,
"Unable to create client for outbound publish '%s'
\n
"
,
ast_sorcery_object_get_id
(
publish
));
return
-
1
;
}
if
(
ast_strlen_zero
(
applied
->
server_uri
))
{
return
0
;
}
static
int
validate_publish_config
(
struct
ast_sip_outbound_publish
*
publish
)
{
if
(
ast_strlen_zero
(
publish
->
server_uri
))
{
ast_log
(
LOG_ERROR
,
"No server URI specified on outbound publish '%s'
\n
"
,
ast_sorcery_object_get_id
(
applied
));
ast_sorcery_object_get_id
(
publish
));
return
-
1
;
}
else
if
(
ast_strlen_zero
(
applied
->
event
))
{
}
else
if
(
ast_strlen_zero
(
publish
->
event
))
{
ast_log
(
LOG_ERROR
,
"No event type specified for outbound publish '%s'
\n
"
,
ast_sorcery_object_get_id
(
applied
));
ast_sorcery_object_get_id
(
publish
));
return
-
1
;
}
return
0
;
}
static
int
current_state_reusable
(
struct
ast_sip_outbound_publish
*
publish
,
struct
ast_sip_outbound_publish_state
*
current_state
)
{
struct
ast_sip_outbound_publish
*
old_publish
;
if
(
!
can_reuse_publish
(
current_state
->
client
->
publish
,
publish
))
{
/*
* Something significant has changed in the configuration, so we are
* unable to use the old state object. The current state needs to go
* away and a new one needs to be created.
*/
return
0
;
}
/*
* We can reuse the current state object so keep it, but swap out the
* underlying publish object with the new one.
*/
old_publish
=
current_state
->
client
->
publish
;
current_state
->
client
->
publish
=
publish
;
if
(
initialize_publish_client
(
publish
,
current_state
))
{
/*
* If the state object fails to re-initialize then swap
* the old publish info back in.
*/
current_state
->
client
->
publish
=
publish
;
return
-
1
;
}
/*
* Since we swapped out the publish object the new one needs a ref
* while the old one needs to go away.
*/
ao2_ref
(
current_state
->
client
->
publish
,
+
1
);
ao2_cleanup
(
old_publish
);
/* Tell the caller that the current state object should be used */
return
1
;
}
/*! \brief Apply function which finds or allocates a state structure */
static
int
sip_outbound_publish_apply
(
const
struct
ast_sorcery
*
sorcery
,
void
*
obj
)
{
#define ADD_TO_NEW_STATES(__obj) \
do { if (__obj) { \
ao2_link(new_states, __obj); \
ao2_ref(__obj, -1); } } while (0)
struct
ast_sip_outbound_publish
*
applied
=
obj
;
struct
ast_sip_outbound_publish_state
*
current_state
,
*
new_state
;
int
res
;
/*
* New states are being loaded or reloaded. We'll need to add the new
* object if created/updated, or keep the old object if an error occurs.
*/
if
(
!
new_states
)
{
/* make sure new_states has been allocated as we will be adding to it */
new_states
=
ao2_container_alloc_options
(
AO2_ALLOC_OPT_LOCK_NOLOCK
,
DEFAULT_STATE_BUCKETS
,
outbound_publish_state_hash
,
outbound_publish_state_cmp
);
...
...
@@ -1115,35 +1187,44 @@ static int sip_outbound_publish_apply(const struct ast_sorcery *sorcery, void *o
}
}
if
(
states
)
{
state
=
ao2_find
(
states
,
ast_sorcery_object_get_id
(
obj
),
OBJ_SEARCH_KEY
);
if
(
state
)
{
if
(
can_reuse_publish
(
state
->
client
->
publish
,
applied
))
{
ao2_replace
(
state
->
client
->
publish
,
applied
);
}
else
{
ao2_ref
(
state
,
-
1
);
state
=
NULL
;
}
}
/* If there is current state we'll want to maintain it if any errors occur */
current_state
=
sip_publish_state_get
(
ast_sorcery_object_get_id
(
applied
));
if
((
res
=
validate_publish_config
(
applied
)))
{
ADD_TO_NEW_STATES
(
current_state
);
return
res
;
}
if
(
!
state
)
{
state
=
sip_outbound_publish_state_alloc
(
applied
);
if
(
!
state
)
{
ast_log
(
LOG_ERROR
,
"Unable to create state for outbound publish '%s'
\n
"
,
ast_sorcery_object_get_id
(
applied
));
return
-
1
;
}
;
if
(
current_state
&&
(
res
=
current_state_reusable
(
applied
,
current_
state
)
))
{
/*
* The current state object was able to be reused, or an error
* occurred. Either way we keep the current state and be done.
*/
ADD_TO_NEW_STATES
(
current_state
)
;
return
res
==
1
?
0
:
-
1
;
}
if
(
ast_sip_push_task_synchronous
(
NULL
,
sip_outbound_publish_client_alloc
,
state
->
client
))
{
ast_log
(
LOG_ERROR
,
"Unable to create client for outbound publish '%s'
\n
"
,
/*
* No current state was found or it was unable to be reused. Either way
* we'll need to create a new state object.
*/
new_state
=
sip_outbound_publish_state_alloc
(
applied
);
if
(
!
new_state
)
{
ast_log
(
LOG_ERROR
,
"Unable to create state for outbound publish '%s'
\n
"
,
ast_sorcery_object_get_id
(
applied
));
ADD_TO_NEW_STATES
(
current_state
);
return
-
1
;
};
if
(
initialize_publish_client
(
applied
,
new_state
))
{
ADD_TO_NEW_STATES
(
current_state
);
ao2_ref
(
new_state
,
-
1
);
return
-
1
;
}
ao2_link
(
new_states
,
state
);
return
0
;
ADD_TO_NEW_STATES
(
new_state
);
ao2_cleanup
(
current_state
);
return
res
;
}
static
int
outbound_auth_handler
(
const
struct
aco_option
*
opt
,
struct
ast_variable
*
var
,
void
*
obj
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment