From: Sung-jae Park Date: Mon, 23 Dec 2013 05:37:20 +0000 (+0900) Subject: Add locking mechanism. X-Git-Tag: submit/tizen_mobile/20150527.071719~2^2~48^2~21^2~95^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bec3906c4972b291866a2ba7b40a3df20a0050bf;p=platform%2Fcore%2Fappfw%2Fdata-provider-master.git Add locking mechanism. for SHM & FILE method for content sharing. Change-Id: I04f6e96195a4e6e01cccc940a96ec28819f54933 --- diff --git a/include/buffer_handler.h b/include/buffer_handler.h index a60c59a..368f8e6 100644 --- a/include/buffer_handler.h +++ b/include/buffer_handler.h @@ -168,4 +168,8 @@ extern void *buffer_handler_raw_data(struct buffer *buffer); extern int buffer_handler_raw_size(struct buffer *buffer); +extern int buffer_handler_lock(struct buffer_info *buffer); + +extern int buffer_handler_unlock(struct buffer_info *buffer); + /* End of a file */ diff --git a/packaging/data-provider-master.spec b/packaging/data-provider-master.spec index 7196eed..cb1c51a 100755 --- a/packaging/data-provider-master.spec +++ b/packaging/data-provider-master.spec @@ -1,6 +1,6 @@ Name: data-provider-master Summary: Master service provider for liveboxes -Version: 0.30.0 +Version: 0.31.0 Release: 1 Group: HomeTF/Livebox License: Flora diff --git a/src/buffer_handler.c b/src/buffer_handler.c index 076ed75..7eeb9e6 100644 --- a/src/buffer_handler.c +++ b/src/buffer_handler.c @@ -87,6 +87,8 @@ struct buffer_info { void *buffer; char *id; + char *lock; + int lock_fd; enum buffer_type type; @@ -112,6 +114,116 @@ static struct { .pixmap_list = NULL, }; +static int destroy_lock_file(struct buffer_info *info) +{ + if (!info->inst) { + return -EINVAL; + } + + if (!info->lock) { + return -EINVAL; + } + + if (close(info->lock_fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + info->lock_fd = -1; + + if (unlink(info->lock) < 0) { + ErrPrint("unlink: %s\n", strerror(errno)); + } + + DbgFree(info->lock); + info->lock = NULL; + return 0; +} + +static int create_lock_file(struct buffer_info *info) +{ + const char *id; + int len; + char *file; + + if (!info->inst) { + return -EINVAL; + } + + id = instance_id(info->inst); + if (!id) { + return -EINVAL; + } + + len = strlen(id); + file = malloc(len + 20); + if (!file) { + ErrPrint("Heap: %s\n", strerror(errno)); + return -ENOMEM; + } + + snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(id), instance_pd_buffer(info->inst) == info ? "pd" : "lb"); + info->lock_fd = open(file, O_WRONLY|O_CREAT, 0644); + if (info->lock_fd < 0) { + ErrPrint("open: %s\n", strerror(errno)); + DbgFree(file); + return -EIO; + } + + info->lock = file; + return 0; +} + +static int do_buffer_lock(struct buffer_info *buffer) +{ + struct flock flock; + int ret; + + if (buffer->lock_fd < 0) { + return 0; + } + + flock.l_type = F_WRLCK; + flock.l_whence = SEEK_SET; + flock.l_start = 0; + flock.l_len = 0; + flock.l_pid = getpid(); + + do { + ret = fcntl(buffer->lock_fd, F_SETLKW, &flock); + if (ret < 0) { + ret = errno; + ErrPrint("fcntl: %s\n", strerror(errno)); + } + } while (ret == EINTR); + + return 0; +} + +static int do_buffer_unlock(struct buffer_info *buffer) +{ + struct flock flock; + int ret; + + if (buffer->lock_fd < 0) { + return 0; + } + + flock.l_type = F_UNLCK; + flock.l_whence = SEEK_SET; + flock.l_start = 0; + flock.l_len = 0; + flock.l_pid = getpid(); + + do { + ret = fcntl(buffer->lock_fd, F_SETLKW, &flock); + if (ret < 0) { + ret = errno; + ErrPrint("fcntl: %s\n", strerror(errno)); + } + } while (ret == EINTR); + + return 0; +} + HAPI struct buffer_info *buffer_handler_create(struct inst_info *inst, enum buffer_type type, int w, int h, int pixel_size) { struct buffer_info *info; @@ -153,6 +265,8 @@ HAPI struct buffer_info *buffer_handler_create(struct inst_info *inst, enum buff return NULL; } + info->lock = NULL; + info->lock_fd = -1; info->w = w; info->h = h; info->pixel_size = pixel_size; @@ -615,9 +729,11 @@ HAPI int buffer_handler_load(struct buffer_info *info) switch (info->type) { case BUFFER_TYPE_FILE: ret = load_file_buffer(info); + (void)create_lock_file(info); break; case BUFFER_TYPE_SHM: ret = load_shm_buffer(info); + (void)create_lock_file(info); break; case BUFFER_TYPE_PIXMAP: ret = load_pixmap_buffer(info); @@ -749,9 +865,11 @@ HAPI int buffer_handler_unload(struct buffer_info *info) switch (info->type) { case BUFFER_TYPE_FILE: + (void)destroy_lock_file(info); ret = unload_file_buffer(info); break; case BUFFER_TYPE_SHM: + (void)destroy_lock_file(info); ret = unload_shm_buffer(info); break; case BUFFER_TYPE_PIXMAP: @@ -787,6 +905,12 @@ HAPI int buffer_handler_destroy(struct buffer_info *info) } buffer_handler_unload(info); + if (info->lock) { + if (unlink(info->lock) < 0) { + ErrPrint("Remove lock: %s (%s)\n", info->lock, strerror(errno)); + } + } + DbgFree(info->id); DbgFree(info); return LB_STATUS_SUCCESS; @@ -1283,9 +1407,11 @@ HAPI void buffer_handler_flush(struct buffer_info *info) } size = info->w * info->h * info->pixel_size; + do_buffer_lock(info); if (write(fd, info->buffer, size) != size) { ErrPrint("Write is not completed: %s\n", strerror(errno)); } + do_buffer_unlock(info); if (close(fd) < 0) { ErrPrint("close: %s\n", strerror(errno)); @@ -1568,4 +1694,30 @@ HAPI int buffer_handler_raw_close(struct buffer *buffer) return ret; } +HAPI int buffer_handler_lock(struct buffer_info *buffer) +{ + if (buffer->type == BUFFER_TYPE_PIXMAP) { + return 0; + } + + if (buffer->type == BUFFER_TYPE_FILE) { + return 0; + } + + return do_buffer_lock(buffer); +} + +HAPI int buffer_handler_unlock(struct buffer_info *buffer) +{ + if (buffer->type == BUFFER_TYPE_PIXMAP) { + return 0; + } + + if (buffer->type == BUFFER_TYPE_FILE) { + return 0; + } + + return do_buffer_unlock(buffer); +} + /* End of a file */ diff --git a/src/fb.c b/src/fb.c index 65a4048..ef46718 100644 --- a/src/fb.c +++ b/src/fb.c @@ -104,6 +104,7 @@ static void sw_render_pre_cb(void *data, Evas *e, void *event_info) buffer_handler_get_size(info->buffer, &w, &h); evas_damage_rectangle_add(e, 0, 0, w, h); + buffer_handler_lock(info->buffer); } static void sw_render_post_cb(void *data, Evas *e, void *event_info) @@ -111,6 +112,7 @@ static void sw_render_post_cb(void *data, Evas *e, void *event_info) void *canvas; Ecore_Evas *internal_ee; int x, y, w, h; + struct fb_info *info = data; internal_ee = ecore_evas_ecore_evas_get(e); if (!internal_ee) { @@ -127,6 +129,7 @@ static void sw_render_post_cb(void *data, Evas *e, void *event_info) ecore_evas_geometry_get(internal_ee, &x, &y, &w, &h); evas_data_argb_unpremul(canvas, w * h); + buffer_handler_unlock(info->buffer); } static void render_pre_cb(void *data, Evas *e, void *event_info) @@ -201,12 +204,15 @@ HAPI int fb_destroy_buffer(struct fb_info *info) return LB_STATUS_ERROR_INVALID; } - if (buffer_handler_type(info->buffer) == BUFFER_TYPE_PIXMAP) { - Evas *e; - e = ecore_evas_get(info->ee); - if (e) { - evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, render_post_cb); - evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb); + Evas *e; + e = ecore_evas_get(info->ee); + if (e) { + if (buffer_handler_type(info->buffer) == BUFFER_TYPE_PIXMAP) { + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, render_post_cb); + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb); + } else { + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, sw_render_post_cb); + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, sw_render_pre_cb); } }