return pvt;
}
+/*!
+ * \internal
+ * \brief Allocate a task processor structure
+ *
+ * \param name Name of the task processor.
+ * \param listener Listener to associate with the task processor.
+ *
+ * \return The newly allocated task processor.
+ *
+ * \pre tps_singletons must be locked by the caller.
+ */
static struct ast_taskprocessor *__allocate_taskprocessor(const char *name, struct ast_taskprocessor_listener *listener)
{
struct ast_taskprocessor *p;
ao2_ref(p, +1);
listener->tps = p;
- if (!(ao2_link(tps_singletons, p))) {
+ if (!(ao2_link_flags(tps_singletons, p, OBJ_NOLOCK))) {
ast_log(LOG_ERROR, "Failed to add taskprocessor '%s' to container\n", p->name);
listener->tps = NULL;
ao2_ref(p, -2);
return NULL;
}
- if (p->listener->callbacks->start(p->listener)) {
+ return p;
+}
+
+static struct ast_taskprocessor *__start_taskprocessor(struct ast_taskprocessor *p)
+{
+ if (p && p->listener->callbacks->start(p->listener)) {
ast_log(LOG_ERROR, "Unable to start taskprocessor listener for taskprocessor %s\n",
p->name);
ast_taskprocessor_unreference(p);
+
return NULL;
}
ast_log(LOG_ERROR, "requesting a nameless taskprocessor!!!\n");
return NULL;
}
- p = ao2_find(tps_singletons, name, OBJ_KEY);
- if (p) {
- return p;
- }
- if (create & TPS_REF_IF_EXISTS) {
+ ao2_lock(tps_singletons);
+ p = ao2_find(tps_singletons, name, OBJ_KEY | OBJ_NOLOCK);
+ if (p || (create & TPS_REF_IF_EXISTS)) {
/* calling function does not want a new taskprocessor to be created if it doesn't already exist */
- return NULL;
+ ao2_unlock(tps_singletons);
+ return p;
}
+
/* Create a new taskprocessor. Start by creating a default listener */
pvt = default_listener_pvt_alloc();
if (!pvt) {
+ ao2_unlock(tps_singletons);
return NULL;
}
listener = ast_taskprocessor_listener_alloc(&default_listener_callbacks, pvt);
if (!listener) {
+ ao2_unlock(tps_singletons);
default_listener_pvt_destroy(pvt);
return NULL;
}
p = __allocate_taskprocessor(name, listener);
-
+ ao2_unlock(tps_singletons);
+ p = __start_taskprocessor(p);
ao2_ref(listener, -1);
+
return p;
}
struct ast_taskprocessor *ast_taskprocessor_create_with_listener(const char *name, struct ast_taskprocessor_listener *listener)
{
- struct ast_taskprocessor *p = ao2_find(tps_singletons, name, OBJ_KEY);
+ struct ast_taskprocessor *p;
+ ao2_lock(tps_singletons);
+ p = ao2_find(tps_singletons, name, OBJ_KEY | OBJ_NOLOCK);
if (p) {
+ ao2_unlock(tps_singletons);
ast_taskprocessor_unreference(p);
return NULL;
}
- return __allocate_taskprocessor(name, listener);
+
+ p = __allocate_taskprocessor(name, listener);
+ ao2_unlock(tps_singletons);
+
+ return __start_taskprocessor(p);
}
void ast_taskprocessor_set_local(struct ast_taskprocessor *tps,