4 * Copyright (C) 2012 Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU Lesser General Public License,
8 * version 2.1, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 * Ludovic Ferrandis <ludovic.ferrandis@intel.com>
25 #include "chain-task.h"
29 typedef struct msu_chain_task_atom_t_ msu_chain_task_atom_t;
30 struct msu_chain_task_atom_t_ {
31 GUPnPServiceProxyActionCallback callback;
32 GUPnPServiceProxyAction *p_action;
33 GDestroyNotify free_func;
35 msu_chain_task_action t_action;
39 struct msu_chain_task_t_ {
40 msu_chain_task_end end_func;
43 msu_chain_task_atom_t *current;
48 static void prv_free_atom(msu_chain_task_atom_t *atom)
50 if (atom->free_func != NULL)
51 atom->free_func(atom->user_data);
56 static gboolean prv_idle_end_func(gpointer user_data)
58 msu_chain_task_t *chain = (msu_chain_task_t *)user_data;
60 chain->end_func(chain, chain->end_data);
64 static gboolean prv_idle_next_task(gpointer user_data)
66 msu_chain_task_t *chain = (msu_chain_task_t *) user_data;
67 GList *head = chain->task_list;
69 chain->task_list = g_list_remove_link(chain->task_list, head);
73 msu_chain_task_start(chain);
78 static void prv_next_task(msu_chain_task_t *chain)
80 chain->idle_id = g_idle_add(prv_idle_next_task, chain);
83 gboolean msu_chain_task_is_canceled(msu_chain_task_t *chain)
85 return chain->canceled;
88 msu_device_t *msu_chain_task_get_device(msu_chain_task_t *chain)
90 if ((chain != NULL) && (chain->current != NULL))
91 return chain->current->device;
96 gpointer *msu_chain_task_get_user_data(msu_chain_task_t *chain)
98 if ((chain != NULL) && (chain->current != NULL))
99 return chain->current->user_data;
104 void msu_chain_task_cancel(msu_chain_task_t *chain)
106 msu_device_t *device;
107 msu_device_context_t *context;
109 if (chain->idle_id) {
110 g_source_remove(chain->idle_id);
114 device = msu_chain_task_get_device(chain);
115 context = msu_device_get_context(device, NULL);
117 if (chain->current->p_action) {
118 gupnp_service_proxy_cancel_action(context->service_proxy,
119 chain->current->p_action);
120 chain->current->p_action = 0;
123 chain->canceled = TRUE;
126 void msu_chain_task_begin_action_cb(GUPnPServiceProxy *proxy,
127 GUPnPServiceProxyAction *action,
130 msu_chain_task_t *chain = (msu_chain_task_t *) user_data;
131 msu_chain_task_atom_t *current;
134 current = chain->current;
136 if (chain->current != NULL) {
137 current->callback(proxy, action, current->user_data);
138 chain->current->p_action = NULL;
141 prv_next_task(chain);
145 void msu_chain_task_start(msu_chain_task_t *chain)
149 if ((chain->task_list != NULL) && (!chain->canceled)) {
150 chain->current = chain->task_list->data;
151 chain->current->p_action = chain->current->t_action(chain,
155 chain->canceled = TRUE;
157 if (chain->current->p_action == NULL &&
158 chain->current->callback == NULL)
159 prv_next_task(chain);
163 chain->idle_id = g_idle_add(prv_idle_end_func, chain);
167 void msu_chain_task_add(msu_chain_task_t *chain,
168 msu_chain_task_action action,
169 msu_device_t *device,
170 GUPnPServiceProxyActionCallback action_cb,
171 GDestroyNotify free_func,
172 gpointer cb_user_data)
174 msu_chain_task_atom_t *atom;
176 atom = g_new0(msu_chain_task_atom_t, 1);
178 atom->t_action = action;
179 atom->callback = action_cb;
180 atom->free_func = free_func;
181 atom->user_data = cb_user_data;
182 atom->device = device;
184 chain->task_list = g_list_append(chain->task_list, atom);
187 void msu_chain_task_delete(msu_chain_task_t *chain)
189 g_list_free_full(chain->task_list, (GDestroyNotify)prv_free_atom);
190 chain->task_list = NULL;
194 msu_chain_task_t *msu_chain_task_new(msu_chain_task_end end_func,
197 msu_chain_task_t *chain;
199 chain = g_new0(msu_chain_task_t, 1);
200 chain->end_func = end_func;
201 chain->end_data = end_data;