1 /*
2 category_store.c
3
4
5
6 2003 Plus Huang
7 */
8
9 #include <stdlib.h>
10 #include "category_store.h"
11 #include "download_thread.h"
12
category_store_init(CategoryStore * cs)13 void category_store_init (CategoryStore* cs)
14 {
15 g_static_rec_mutex_init (&cs->mutex);
16 cs->n_thread = 0;
17 cs->n_thread_limit = 1;
18
19 cs->list_store = gtk_list_store_new (CATEGORY_N_COL,
20 G_TYPE_POINTER,
21 G_TYPE_POINTER,
22 G_TYPE_POINTER);
23
24 cs->tree_store = gtk_tree_store_new (CATEGORY_N_COL,
25 G_TYPE_POINTER,
26 G_TYPE_POINTER,
27 G_TYPE_POINTER);
28 }
29
category_store_clear(CategoryStore * cs)30 void category_store_clear (CategoryStore* cs)
31 {
32 g_object_unref (cs->list_store);
33 g_object_unref (cs->tree_store);
34 }
35
category_store_append(CategoryStore * cs,Category * cate)36 void category_store_append (CategoryStore* cs,
37 Category* cate)
38 {
39 GtkTreeIter iter_child;
40
41 category_store_lock (cs);
42
43 cate->category_store = cs;
44 cate->valid = TRUE;
45
46 // append data to GtkListStore
47 gtk_list_store_append (cs->list_store,
48 &cate->iter_list_store);
49 gtk_list_store_set (cs->list_store,
50 &cate->iter_list_store,
51 CATEGORY_COL_DATA, cate,
52 CATEGORY_COL_DOWNLOAD_STORE, &cate->waiting_store,
53 CATEGORY_COL_DOWNLOAD_VIEW, &cate->waiting_view,
54 -1);
55
56 // append data to GtkTreeStore
57 gtk_tree_store_append (cs->tree_store,
58 &cate->iter_tree_store, NULL);
59 gtk_tree_store_set (cs->tree_store,
60 &cate->iter_tree_store,
61 CATEGORY_COL_DATA, cate,
62 CATEGORY_COL_DOWNLOAD_STORE, &cate->waiting_store,
63 CATEGORY_COL_DOWNLOAD_VIEW, &cate->waiting_view,
64 -1);
65 gtk_tree_store_append (cs->tree_store,
66 &iter_child,
67 &cate->iter_tree_store);
68 gtk_tree_store_set (cs->tree_store,
69 &iter_child,
70 CATEGORY_COL_DATA, cate,
71 CATEGORY_COL_DOWNLOAD_STORE, &cate->completed_store,
72 CATEGORY_COL_DOWNLOAD_VIEW, &cate->completed_view,
73 -1);
74 gtk_tree_store_append (cs->tree_store,
75 &iter_child,
76 &cate->iter_tree_store);
77 gtk_tree_store_set (cs->tree_store,
78 &iter_child,
79 CATEGORY_COL_DATA, cate,
80 CATEGORY_COL_DOWNLOAD_STORE, &cate->recycled_store,
81 CATEGORY_COL_DOWNLOAD_VIEW, &cate->recycled_view,
82 -1);
83
84 category_store_unlock (cs);
85 }
86
category_store_erase(CategoryStore * cs,Category * category)87 void category_store_erase (CategoryStore* cs,
88 Category* category)
89 {
90 category_store_lock (cs);
91
92 category->valid = FALSE;
93 category_thread_destroy (category);
94 category_unref (category);
95
96 gtk_list_store_remove (cs->list_store, &category->iter_list_store);
97 gtk_tree_store_remove (cs->tree_store, &category->iter_tree_store);
98
99 category_store_unlock (cs);
100 }
101
category_store_get_next(CategoryStore * cs,Category * category)102 Category* category_store_get_next (CategoryStore* cs,
103 Category* category)
104 {
105 GtkTreeIter iter;
106 gboolean valid = FALSE;
107 Category* next_category = NULL;
108
109 if (category == NULL || category->valid==FALSE ) {
110 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (cs->list_store),
111 &iter);
112 }
113 else {
114 iter = category->iter_list_store;
115 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (cs->list_store),
116 &iter);
117 if (valid==FALSE) {
118 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (cs->list_store),
119 &iter);
120 }
121 }
122
123 if (valid) {
124 gtk_tree_model_get (GTK_TREE_MODEL (cs->list_store), &iter,
125 CATEGORY_COL_DATA, &next_category, -1);
126 if (next_category == category)
127 return NULL;
128 }
129
130 return next_category;
131 }
132
133 // thread operate for CategoryStore
category_store_thread_count_request(CategoryStore * cs)134 gint category_store_thread_count_request (CategoryStore* cs)
135 {
136 return cs->n_thread_limit - cs->n_thread;
137 }
138
category_store_thread_ref(CategoryStore * cs)139 void category_store_thread_ref (CategoryStore* cs)
140 {
141 category_store_lock (cs);
142 cs->n_thread++;
143 printf ("active category %d\n", cs->n_thread);
144 category_store_unlock (cs);
145 }
146
category_store_thread_unref(CategoryStore * cs)147 void category_store_thread_unref (CategoryStore* cs)
148 {
149 category_store_lock (cs);
150 cs->n_thread--;
151 printf ("active category %d\n", cs->n_thread);
152 category_store_unlock (cs);
153 }
154
category_store_thread_activate_1(CategoryStore * cs,Category * category)155 void category_store_thread_activate_1 (CategoryStore* cs,
156 Category* category)
157 {
158 category_lock (category);
159 category_store_lock (cs);
160
161 // try to activate another download thread in category until limit
162 if (category_thread_is_active (category) ||
163 category_store_thread_count_request (cs) > 0)
164 {
165 category_thread_activate (category);
166 }
167
168 category_store_unlock (cs);
169 category_unlock (category);
170 }
171
172 /*
173 void category_store_thread_stop_1 (CategoryStore* cs,
174 Category* category)
175 {
176 Category* first_category;
177 Category* next_category;
178
179 category_lock (category);
180 category_store_lock (cs);
181
182 category_thread_destroy (category);
183 cs->n_thread--;
184
185 category_store_unlock (cs);
186 category_unlock (category);
187
188 category_store_thread_activate_next (cs, category);
189 }
190 */
191
category_store_thread_activate_next(CategoryStore * cs,Category * category)192 void category_store_thread_activate_next (CategoryStore* cs,
193 Category* category)
194 {
195 Category* first_category;
196 Category* next_category;
197
198 category_store_lock (cs);
199
200 next_category = first_category = category_store_get_next (cs, category);
201
202 while (next_category) {
203 if (category_store_thread_count_request (cs) < 1)
204 break;
205
206 category_thread_activate (next_category);
207
208 next_category = category_store_get_next (cs, next_category);
209
210 if (next_category==first_category || next_category==category)
211 break;
212 }
213
214 category_store_unlock (cs);
215 }
216
category_store_thread_activate(CategoryStore * cs)217 void category_store_thread_activate (CategoryStore* cs)
218 {
219 Category* category;
220 GtkTreeIter iter;
221 gboolean valid;
222
223 category_store_lock (cs);
224
225 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (cs->list_store),
226 &iter);
227 while (valid) {
228 gtk_tree_model_get ( (GtkTreeModel*)cs->list_store,
229 &iter,
230 CATEGORY_COL_DATA, &category,
231 -1);
232 category_store_thread_activate_1 (cs, category);
233 valid = gtk_tree_model_iter_next ( (GtkTreeModel*)cs->list_store,
234 &iter);
235 }
236
237 category_store_unlock (cs);
238 }
239
category_store_thread_stop(CategoryStore * cs)240 void category_store_thread_stop (CategoryStore* cs)
241 {
242 Category* category;
243 GtkTreeIter iter;
244 gboolean valid;
245
246 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (cs->list_store),
247 &iter);
248 while (valid) {
249 gtk_tree_model_get ( (GtkTreeModel*)cs->list_store,
250 &iter,
251 CATEGORY_COL_DATA, &category,
252 -1);
253 category_thread_stop (category);
254 valid = gtk_tree_model_iter_next ( (GtkTreeModel*)cs->list_store,
255 &iter);
256 }
257 }
258
category_store_thread_destroy(CategoryStore * cs)259 void category_store_thread_destroy (CategoryStore* cs)
260 {
261 Category* category;
262 GtkTreeIter iter;
263 gboolean valid;
264
265 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (cs->list_store),
266 &iter);
267 while (valid) {
268 gtk_tree_model_get ( (GtkTreeModel*)cs->list_store,
269 &iter,
270 CATEGORY_COL_DATA, &category,
271 -1);
272 category_thread_destroy (category);
273 valid = gtk_tree_model_iter_next ( (GtkTreeModel*)cs->list_store,
274 &iter);
275 }
276 }
277
278