dd9d5b55d72699c035ea11e292c4a6f1aa1d7306
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_resource.c
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "mm_camcorder_internal.h"
21 #include "mm_camcorder_resource.h"
22 #include <murphy/common/glib-glue.h>
23
24 #define MRP_APP_CLASS_FOR_CAMCORDER   "media"
25 #define MRP_RESOURCE_TYPE_MANDATORY TRUE
26 #define MRP_RESOURCE_TYPE_EXCLUSIVE FALSE
27
28 const char* mm_camcorder_resource_str[MM_CAMCORDER_RESOURCE_MAX] = {
29         "camera",
30         "video_overlay",
31         "video_encoder"
32 };
33
34 #define MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(x_camcorder_resource_manager) \
35 do { \
36         if (!x_camcorder_resource_manager) { \
37                 _mmcam_dbg_err("no resource manager instance"); \
38                 return MM_ERROR_INVALID_ARGUMENT; \
39         } \
40 } while (0);
41
42 #define MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(x_camcorder_resource_manager) \
43 do { \
44         if (!x_camcorder_resource_manager) { \
45                 _mmcam_dbg_err("no resource manager instance"); \
46                 return MM_ERROR_INVALID_ARGUMENT; \
47         } else { \
48                 if (!x_camcorder_resource_manager->is_connected) { \
49                         _mmcam_dbg_err("not connected to resource server yet"); \
50                         return MM_ERROR_RESOURCE_NOT_INITIALIZED; \
51                 } \
52         } \
53 } while (0);
54
55 #define RESOURCE_LOG_INFO(fmt, args...) \
56 do { \
57         _mmcam_dbg_log("[%p][ID:%d] "fmt, resource_manager, resource_manager->id, ##args); \
58 } while (0);
59
60 #define RESOURCE_LOG_WARN(fmt, args...) \
61 do { \
62         _mmcam_dbg_warn("[%p][ID:%d] "fmt, resource_manager, resource_manager->id, ##args); \
63 } while (0);
64
65 #define RESOURCE_LOG_ERR(fmt, args...) \
66 do { \
67         _mmcam_dbg_err("[%p][ID:%d] "fmt, resource_manager, resource_manager->id, ##args); \
68 } while (0);
69
70 static char *__mmcamcorder_resource_state_to_str(mrp_res_resource_state_t st)
71 {
72         char *state = "unknown";
73         switch (st) {
74         case MRP_RES_RESOURCE_ACQUIRED:
75                 state = "acquired";
76                 break;
77         case MRP_RES_RESOURCE_LOST:
78                 state = "lost";
79                 break;
80         case MRP_RES_RESOURCE_AVAILABLE:
81                 state = "available";
82                 break;
83         case MRP_RES_RESOURCE_PENDING:
84                 state = "pending";
85                 break;
86         case MRP_RES_RESOURCE_ABOUT_TO_LOOSE:
87                 state = "about to loose";
88                 break;
89         }
90         return state;
91 }
92
93 static void __mmcamcorder_resource_state_callback(mrp_res_context_t *context, mrp_res_error_t err, void *user_data)
94 {
95         int i = 0;
96         const mrp_res_resource_set_t *rset;
97         mrp_res_resource_t *resource;
98         mmf_camcorder_t *hcamcorder = NULL;
99         MMCamcorderResourceManager *resource_manager = (MMCamcorderResourceManager *)user_data;
100
101         mmf_return_if_fail(context);
102         mmf_return_if_fail(resource_manager);
103
104         hcamcorder = (mmf_camcorder_t *)resource_manager->hcamcorder;
105
106         mmf_return_if_fail(hcamcorder);
107
108         RESOURCE_LOG_WARN("enter - state %d", context->state);
109
110         _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
111
112         switch (context->state) {
113         case MRP_RES_CONNECTED:
114                 RESOURCE_LOG_WARN(" - connected to Murphy");
115                 if ((rset = mrp_res_list_resources(context)) != NULL) {
116                         mrp_res_string_array_t *resource_names;
117                         resource_names = mrp_res_list_resource_names(rset);
118                         if (!resource_names) {
119                                 RESOURCE_LOG_ERR(" - no resources available");
120                                 _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
121                                 return;
122                         }
123                         for (i = 0; i < resource_names->num_strings; i++) {
124                                 resource = mrp_res_get_resource_by_name(rset, resource_names->strings[i]);
125                                 if (resource)
126                                         RESOURCE_LOG_WARN(" - available resource: %s", resource->name);
127                         }
128                         mrp_res_free_string_array(resource_names);
129                 }
130                 resource_manager->is_connected = TRUE;
131                 _MMCAMCORDER_RESOURCE_SIGNAL(hcamcorder);
132                 break;
133         case MRP_RES_DISCONNECTED:
134                 RESOURCE_LOG_ERR(" - disconnected from Murphy : stop camcorder");
135
136                 if (resource_manager->rset) {
137                         mrp_res_delete_resource_set(resource_manager->rset);
138                         resource_manager->rset = NULL;
139                 }
140
141                 if (resource_manager->context) {
142                         mrp_res_destroy(resource_manager->context);
143                         resource_manager->context = NULL;
144                         resource_manager->is_connected = FALSE;
145                 }
146
147                 _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
148
149                 _MMCAMCORDER_LOCK_ASM(hcamcorder);
150
151                 /* Stop the camera */
152                 __mmcamcorder_force_stop(hcamcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
153
154                 _MMCAMCORDER_UNLOCK_ASM(hcamcorder);
155
156                 _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
157                 break;
158         }
159
160         _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
161
162         RESOURCE_LOG_WARN("leave");
163
164         return;
165 }
166
167
168 static void __mmcamcorder_resource_set_state_callback(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
169 {
170         int i = 0;
171         mmf_camcorder_t *hcamcorder = NULL;
172         MMCamcorderResourceManager *resource_manager = (MMCamcorderResourceManager *)user_data;
173         mrp_res_resource_t *res = NULL;
174
175         mmf_return_if_fail(resource_manager && resource_manager->hcamcorder);
176
177         hcamcorder = (mmf_camcorder_t *)resource_manager->hcamcorder;
178
179         RESOURCE_LOG_WARN("start");
180
181         _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
182
183         if (!mrp_res_equal_resource_set(rs, resource_manager->rset)) {
184                 RESOURCE_LOG_WARN("- resource set(%p) is not same as this handle's(%p)", rs, resource_manager->rset);
185                 _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
186                 return;
187         }
188
189         RESOURCE_LOG_INFO(" - resource set state is changed to [%s]", __mmcamcorder_resource_state_to_str(rs->state));
190
191         for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
192                 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
193                 if (res == NULL) {
194                         RESOURCE_LOG_WARN(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
195                 } else {
196                         RESOURCE_LOG_WARN(" -- resource name [%s] -> [%s]",
197                                 res->name, __mmcamcorder_resource_state_to_str(res->state));
198
199                         if (res->state == MRP_RES_RESOURCE_ACQUIRED) {
200                                 resource_manager->acquire_remain--;
201
202                                 if (resource_manager->acquire_remain <= 0) {
203                                         RESOURCE_LOG_WARN("send signal - resource acquire done");
204                                         _MMCAMCORDER_RESOURCE_SIGNAL(hcamcorder);
205                                 } else {
206                                         RESOURCE_LOG_WARN("remained acquire count %d",
207                                                 resource_manager->acquire_remain);
208                                 }
209                         } else if (res->state == MRP_RES_RESOURCE_LOST) {
210                                 resource_manager->acquire_remain++;
211
212                                 if (resource_manager->acquire_remain >= resource_manager->acquire_count) {
213                                         RESOURCE_LOG_WARN("resource release done");
214
215                                         if (hcamcorder->state > MM_CAMCORDER_STATE_NULL) {
216                                                 RESOURCE_LOG_WARN("send resource signal");
217                                                 _MMCAMCORDER_RESOURCE_SIGNAL(hcamcorder);
218                                         } else {
219                                                 RESOURCE_LOG_WARN("skip resource signal - state %d", hcamcorder->state);
220                                         }
221                                 } else {
222                                         RESOURCE_LOG_WARN("acquired %d, lost %d",
223                                                 resource_manager->acquire_count, resource_manager->acquire_remain);
224                                 }
225                         }
226                 }
227         }
228
229         mrp_res_delete_resource_set(resource_manager->rset);
230         resource_manager->rset = mrp_res_copy_resource_set(rs);
231
232         _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
233
234         RESOURCE_LOG_WARN("done");
235
236         return;
237 }
238
239
240 static void __mmcamcorder_resource_release_cb(mrp_res_context_t *cx, const mrp_res_resource_set_t *rs, void *user_data)
241 {
242         int i = 0;
243         int current_state = MM_CAMCORDER_STATE_NONE;
244         mmf_camcorder_t *hcamcorder = NULL;
245         MMCamcorderResourceManager *resource_manager = (MMCamcorderResourceManager *)user_data;
246         mrp_res_resource_t *res = NULL;
247
248         mmf_return_if_fail(resource_manager && resource_manager->hcamcorder);
249
250         hcamcorder = (mmf_camcorder_t *)resource_manager->hcamcorder;
251
252         current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
253         if (current_state <= MM_CAMCORDER_STATE_NONE ||
254             current_state >= MM_CAMCORDER_STATE_NUM) {
255                 RESOURCE_LOG_ERR("Abnormal state %d", current_state);
256                 return;
257         }
258
259         RESOURCE_LOG_WARN("enter");
260
261         _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
262
263         if (!mrp_res_equal_resource_set(rs, resource_manager->rset)) {
264                 _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
265                 RESOURCE_LOG_WARN("- resource set(%p) is not same as this handle's(%p)", rs, resource_manager->rset);
266                 return;
267         }
268
269         /* set flag for resource release callback */
270         resource_manager->is_release_cb_calling = TRUE;
271
272         RESOURCE_LOG_INFO(" - resource set state is changed to [%s]", __mmcamcorder_resource_state_to_str(rs->state));
273
274         for (i = 0; i < MM_CAMCORDER_RESOURCE_MAX; i++) {
275                 res = mrp_res_get_resource_by_name(rs, mm_camcorder_resource_str[i]);
276                 if (res) {
277                         RESOURCE_LOG_WARN(" -- resource name [%s] -> [%s]",
278                                 res->name, __mmcamcorder_resource_state_to_str(res->state));
279                 } else {
280                         RESOURCE_LOG_WARN(" -- %s not present in resource set", mm_camcorder_resource_str[i]);
281                 }
282         }
283
284         _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
285
286         _MMCAMCORDER_LOCK_ASM(hcamcorder);
287
288         if (resource_manager->id == MM_CAMCORDER_RESOURCE_ID_MAIN) {
289                 /* Stop camera */
290                 __mmcamcorder_force_stop(hcamcorder, _MMCAMCORDER_STATE_CHANGE_BY_RM);
291         } else {
292                 /* Stop video recording */
293                 if (_mmcamcorder_commit((MMHandleType)hcamcorder) != MM_ERROR_NONE) {
294                         RESOURCE_LOG_ERR("commit failed, cancel it");
295                         _mmcamcorder_cancel((MMHandleType)hcamcorder);
296                 }
297         }
298
299         _MMCAMCORDER_UNLOCK_ASM(hcamcorder);
300
301         _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
302
303         /* restore flag for resource release callback */
304         resource_manager->is_release_cb_calling = FALSE;
305
306         _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
307
308         RESOURCE_LOG_WARN("leave");
309
310         return;
311 }
312
313 int _mmcamcorder_resource_create_resource_set(MMCamcorderResourceManager *resource_manager)
314 {
315         if (resource_manager->rset) {
316                 RESOURCE_LOG_WARN(" - resource set was already created, delete it");
317                 mrp_res_delete_resource_set(resource_manager->rset);
318                 resource_manager->rset = NULL;
319         }
320
321         resource_manager->rset = mrp_res_create_resource_set(resource_manager->context,
322                 MRP_APP_CLASS_FOR_CAMCORDER, __mmcamcorder_resource_set_state_callback, (void *)resource_manager);
323
324         if (resource_manager->rset == NULL) {
325                 RESOURCE_LOG_ERR(" - could not create resource set");
326                 return MM_ERROR_RESOURCE_INTERNAL;
327         }
328
329         if (!mrp_res_set_autorelease(TRUE, resource_manager->rset))
330                 RESOURCE_LOG_WARN(" - could not set autorelease flag!");
331
332         RESOURCE_LOG_INFO("done");
333
334         return MM_ERROR_NONE;
335 }
336
337 static int __mmcamcorder_resource_include_resource(MMCamcorderResourceManager *resource_manager, const char *resource_name)
338 {
339         mrp_res_resource_t *resource = NULL;
340         resource = mrp_res_create_resource(resource_manager->rset,
341                 resource_name,
342                 MRP_RESOURCE_TYPE_MANDATORY,
343                 MRP_RESOURCE_TYPE_EXCLUSIVE);
344         if (resource == NULL) {
345                 RESOURCE_LOG_ERR(" - could not include resource[%s]", resource_name);
346                 return MM_ERROR_RESOURCE_INTERNAL;
347         }
348
349         resource_manager->acquire_count++;
350         resource_manager->acquire_remain = resource_manager->acquire_count;
351
352         RESOURCE_LOG_INFO(" - count[%d] include resource[%s]",
353                 resource_manager->acquire_count, resource_name);
354
355         return MM_ERROR_NONE;
356 }
357
358 static int __mmcamcorder_resource_set_release_cb(MMCamcorderResourceManager *resource_manager)
359 {
360         int ret = MM_ERROR_NONE;
361         bool mrp_ret = FALSE;
362
363         if (resource_manager->rset) {
364                 mrp_ret = mrp_res_set_release_callback(resource_manager->rset, __mmcamcorder_resource_release_cb, (void *)resource_manager);
365                 if (!mrp_ret) {
366                         RESOURCE_LOG_ERR(" - could not set release callback");
367                         ret = MM_ERROR_RESOURCE_INTERNAL;
368                 }
369         } else {
370                 RESOURCE_LOG_ERR(" - resource set is null");
371                 ret = MM_ERROR_RESOURCE_INVALID_STATE;
372         }
373
374         return ret;
375 }
376
377 int _mmcamcorder_resource_manager_init(MMCamcorderResourceManager *resource_manager)
378 {
379         GMainContext *mrp_ctx = NULL;
380         GMainLoop *mrp_loop = NULL;
381
382         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
383
384         RESOURCE_LOG_WARN("start");
385
386         mrp_ctx = g_main_context_new();
387         if (!mrp_ctx) {
388                 RESOURCE_LOG_ERR("failed to get create glib context for mrp");
389                 return MM_ERROR_RESOURCE_INTERNAL;
390         }
391
392         mrp_loop = g_main_loop_new(mrp_ctx, TRUE);
393
394         g_main_context_unref(mrp_ctx);
395         mrp_ctx = NULL;
396
397         if (!mrp_loop) {
398                 RESOURCE_LOG_ERR("failed to get create glib loop for mrp");
399                 return MM_ERROR_RESOURCE_INTERNAL;
400         }
401
402         resource_manager->mloop = mrp_mainloop_glib_get(mrp_loop);
403
404         g_main_loop_unref(mrp_loop);
405         mrp_loop = NULL;
406
407         if (!resource_manager->mloop) {
408                 RESOURCE_LOG_ERR("failed to get mainloop for mrp");
409                 return MM_ERROR_RESOURCE_INTERNAL;
410         }
411
412         RESOURCE_LOG_WARN("mloop %p", resource_manager->mloop);
413
414         resource_manager->context = mrp_res_create(resource_manager->mloop, __mmcamcorder_resource_state_callback, (void *)resource_manager);
415         if (!resource_manager->context) {
416                 RESOURCE_LOG_ERR("could not get context for mrp");
417
418                 mrp_mainloop_destroy(resource_manager->mloop);
419                 resource_manager->mloop = NULL;
420
421                 return MM_ERROR_RESOURCE_INTERNAL;
422         }
423
424         RESOURCE_LOG_INFO("done");
425
426         return MM_ERROR_NONE;
427 }
428
429
430 int _mmcamcorder_resource_wait_for_connection(MMCamcorderResourceManager *resource_manager)
431 {
432         int ret = MM_ERROR_NONE;
433         void *hcamcorder = NULL;
434
435         mmf_return_val_if_fail(resource_manager && resource_manager->hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
436
437         hcamcorder = resource_manager->hcamcorder;
438
439         _MMCAMCORDER_LOCK_RESOURCE(hcamcorder);
440
441         if (resource_manager->is_connected == FALSE) {
442                 gint64 end_time = 0;
443
444                 /* wait for resource manager connected */
445                 RESOURCE_LOG_WARN("not connected. wait for signal...");
446
447                 end_time = g_get_monotonic_time() + (__MMCAMCORDER_RESOURCE_WAIT_TIME * G_TIME_SPAN_SECOND);
448
449                 if (_MMCAMCORDER_RESOURCE_WAIT_UNTIL(hcamcorder, end_time)) {
450                         RESOURCE_LOG_WARN("signal received");
451                         ret = MM_ERROR_NONE;
452                 } else {
453                         RESOURCE_LOG_ERR("connection timeout");
454                         ret = MM_ERROR_RESOURCE_INTERNAL;
455                 }
456         } else {
457                 RESOURCE_LOG_WARN("already connected");
458         }
459
460         _MMCAMCORDER_UNLOCK_RESOURCE(hcamcorder);
461
462         return ret;
463 }
464
465
466 int _mmcamcorder_resource_check_connection(MMCamcorderResourceManager *resource_manager)
467 {
468         int ret = MM_ERROR_NONE;
469
470         mmf_return_val_if_fail(resource_manager, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
471
472         if (resource_manager->is_connected == FALSE) {
473                 RESOURCE_LOG_WARN("resource manager disconnected before, try to reconnect");
474
475                 /* release remained resource */
476                 _mmcamcorder_resource_manager_deinit(resource_manager);
477
478                 /* init resource manager and wait for connection */
479                 ret = _mmcamcorder_resource_manager_init(resource_manager);
480                 if (ret != MM_ERROR_NONE) {
481                         RESOURCE_LOG_ERR("failed to initialize resource manager");
482                         return ret;
483                 }
484
485                 ret = _mmcamcorder_resource_wait_for_connection(resource_manager);
486                 if (ret != MM_ERROR_NONE) {
487                         RESOURCE_LOG_ERR("failed to connect resource manager");
488                         return ret;
489                 }
490         }
491
492         RESOURCE_LOG_WARN("done");
493
494         return ret;
495 }
496
497
498 int _mmcamcorder_resource_manager_prepare(MMCamcorderResourceManager *resource_manager, MMCamcorderResourceType resource_type)
499 {
500         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
501         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
502
503         return __mmcamcorder_resource_include_resource(resource_manager, mm_camcorder_resource_str[resource_type]);
504 }
505
506 int _mmcamcorder_resource_manager_acquire(MMCamcorderResourceManager *resource_manager)
507 {
508         int ret = MM_ERROR_NONE;
509         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
510         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
511
512         if (resource_manager->rset == NULL) {
513                 RESOURCE_LOG_ERR("- could not acquire resource, resource set is null");
514                 ret = MM_ERROR_RESOURCE_INVALID_STATE;
515         } else {
516                 ret = __mmcamcorder_resource_set_release_cb(resource_manager);
517                 if (ret) {
518                         RESOURCE_LOG_ERR("- could not set resource release cb, ret(%d)", ret);
519                         ret = MM_ERROR_RESOURCE_INTERNAL;
520                 } else {
521                         ret = mrp_res_acquire_resource_set(resource_manager->rset);
522                         if (ret) {
523                                 RESOURCE_LOG_ERR("- could not acquire resource, ret(%d)", ret);
524                                 ret = MM_ERROR_RESOURCE_INTERNAL;
525                         }
526                 }
527         }
528
529         return ret;
530 }
531
532 int _mmcamcorder_resource_manager_release(MMCamcorderResourceManager *resource_manager)
533 {
534         int ret = MM_ERROR_NONE;
535         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
536         MMCAMCORDER_CHECK_CONNECTION_RESOURCE_MANAGER(resource_manager);
537
538         if (resource_manager->rset == NULL) {
539                 RESOURCE_LOG_ERR("- could not release resource, resource set is null");
540                 ret = MM_ERROR_RESOURCE_INVALID_STATE;
541         } else {
542                 if (resource_manager->rset->state != MRP_RES_RESOURCE_ACQUIRED) {
543                         RESOURCE_LOG_ERR("- could not release resource, resource set state is [%s]",
544                                 __mmcamcorder_resource_state_to_str(resource_manager->rset->state));
545                         ret = MM_ERROR_RESOURCE_INVALID_STATE;
546                 } else {
547                         ret = mrp_res_release_resource_set(resource_manager->rset);
548                         if (ret) {
549                                 RESOURCE_LOG_ERR("- could not release resource, ret(%d)", ret);
550                                 ret = MM_ERROR_RESOURCE_INTERNAL;
551                         } else {
552                                 RESOURCE_LOG_INFO("resource release done");
553                         }
554                 }
555         }
556
557         return ret;
558 }
559
560
561 int _mmcamcorder_resource_manager_deinit(MMCamcorderResourceManager *resource_manager)
562 {
563         MMCAMCORDER_CHECK_RESOURCE_MANAGER_INSTANCE(resource_manager);
564
565         RESOURCE_LOG_WARN("rset %p, context %p, mloop %p",
566                 resource_manager->rset, resource_manager->context, resource_manager->mloop);
567
568         if (resource_manager->rset) {
569                 if (resource_manager->rset->state == MRP_RES_RESOURCE_ACQUIRED) {
570                         RESOURCE_LOG_WARN("resource is still acquired. release...");
571                         if (mrp_res_release_resource_set(resource_manager->rset))
572                                 RESOURCE_LOG_ERR("- could not release resource");
573                 }
574
575                 RESOURCE_LOG_WARN("delete resource set");
576
577                 mrp_res_delete_resource_set(resource_manager->rset);
578                 resource_manager->rset = NULL;
579         }
580
581         if (resource_manager->context) {
582                 RESOURCE_LOG_WARN("destroy resource context");
583
584                 mrp_res_destroy(resource_manager->context);
585                 resource_manager->context = NULL;
586         }
587
588         if (resource_manager->mloop) {
589                 RESOURCE_LOG_WARN("destroy resource mainloop");
590
591                 mrp_mainloop_quit(resource_manager->mloop, 0);
592                 mrp_mainloop_destroy(resource_manager->mloop);
593                 resource_manager->mloop = NULL;
594         }
595
596         RESOURCE_LOG_WARN("done");
597
598         return MM_ERROR_NONE;
599 }