rimmed pushed a commit to branch master.

http://git.enlightenment.org/tools/eflete.git/commit/?id=b354edb350febb9598b2ce1f0a509ea8dc999801

commit b354edb350febb9598b2ce1f0a509ea8dc999801
Author: Vyacheslav Reutskiy <v.reuts...@samsung.com>
Date:   Tue Apr 19 17:38:46 2016 +0300

    project_manager: add the project lock
    
    This feature helps to denied open one project in several Eflete
    
    Change-Id: Id11f5591b7ee44f687db11ee86338f750de89639
---
 src/bin/project_manager/project_manager.c | 52 +++++++++++++++++++++++++++++--
 src/bin/project_manager/project_manager.h | 13 ++++++++
 src/bin/ui/project_common.c               |  5 +++
 src/bin/ui/tab_home_common.c              |  6 ++++
 4 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/src/bin/project_manager/project_manager.c 
b/src/bin/project_manager/project_manager.c
index d0cc1a3..c6aa26d 100644
--- a/src/bin/project_manager/project_manager.c
+++ b/src/bin/project_manager/project_manager.c
@@ -153,6 +153,33 @@ _project_dev_file_create(Project *pro)
 
 static Eet_Data_Descriptor *eed_project = NULL;
 
+static Eina_Bool
+_lock_try(const char *path, Eina_Bool check)
+{
+   struct flock lock, savelock;
+
+   int fd = open(path, O_RDWR);
+   lock.l_type    = F_WRLCK;   /* Test for any lock on any part of file. */
+   lock.l_whence  = SEEK_SET;
+   lock.l_start   = 0;
+   lock.l_len     = 0;
+   savelock = lock;
+   fcntl(fd, F_GETLK, &lock);  /* Overwrites lock structure with preventors. */
+   if ((lock.l_type == F_WRLCK) || (lock.l_type == F_RDLCK))
+     {
+        ERR("Process %d has a write lock already!", lock.l_pid);
+        return false;
+     }
+   /* if flag check is false not need to lock the file */
+   if (!check)
+     {
+        savelock.l_pid = getpid();
+        fcntl(fd, F_SETLK, &savelock);
+     }
+
+   return true;
+}
+
 static void
 _project_descriptor_init(void)
 {
@@ -426,13 +453,20 @@ _project_import_edj(void *data,
 {
    Eina_Bool send_end = (data) ? (*(Eina_Bool *)data) : true;
 
+   THREAD_TESTCANCEL;
+   worker.project->pro_path = eina_stringshare_printf("%s/%s/%s.pro", 
worker.path, worker.name, worker.name);
+   if (!_lock_try(worker.project->pro_path, true))
+     {
+        /* really this case is unlickly, but we need handle it */
+        END_SEND(PM_PROJECT_LOCKED);
+        return NULL;
+     }
+
    PROGRESS_SEND(_("Start import '%s' file as new project"), worker.edj);
    PROGRESS_SEND(_("Creating a specifiec file and folders"));
    worker.project = _project_files_create();
    TODO("Add correct error handling here (if project == NULL). Probably we 
should add negative TC where directory already exist");
    THREAD_TESTCANCEL;
-   worker.project->pro_path = eina_stringshare_printf("%s/%s/%s.pro", 
worker.path, worker.name, worker.name);
-   THREAD_TESTCANCEL;
    PROGRESS_SEND(_("Import processing"));
    _project_edj_file_copy();
    _copy_meta_data_to_pro();
@@ -624,6 +658,13 @@ _project_open(void *data,
 
    edje_file_cache_flush();
 
+   if (!_lock_try(path, true))
+     {
+        /* really this case is unlickly, but we need handle it */
+        END_SEND(PM_PROJECT_LOCKED);
+        return NULL;
+     }
+
    PROGRESS_SEND(_("Opening project \"%s\""), path);
 
    _project_descriptor_init();
@@ -1769,4 +1810,11 @@ pm_project_enventor_save(Project *project,
         abort();
      }
 }
+
 #endif /* HAVE_ENVENTOR */
+
+Eina_Bool
+pm_lock_check(const char *path)
+{
+   return _lock_try(path, false);
+}
diff --git a/src/bin/project_manager/project_manager.h 
b/src/bin/project_manager/project_manager.h
index 2658fea..6301102 100644
--- a/src/bin/project_manager/project_manager.h
+++ b/src/bin/project_manager/project_manager.h
@@ -136,6 +136,7 @@ enum _PM_Project_Result
    PM_PROJECT_SUCCESS,
    PM_PROJECT_CANCEL,
    PM_PROJECT_ERROR,
+   PM_PROJECT_LOCKED,
    PM_PROJECT_LAST
 };
 
@@ -522,6 +523,18 @@ pm_project_enventor_save(Project *project,
                          const void *data) EINA_ARG_NONNULL(1);
 
 /**
+ * Check the lock of given file.
+ *
+ * @param path The path to checked file
+ *
+ * @return EINA_TRUE if file not locked, owerise EINA_FALSE.
+ *
+ * @ingroup ProjectManager
+ */
+Eina_Bool
+pm_lock_check(const char *path) EINA_ARG_NONNULL(1);
+
+/**
  * @struct _Resource
  *
  * Common structure for resources that can be used somewhere (images, sounds,
diff --git a/src/bin/ui/project_common.c b/src/bin/ui/project_common.c
index e3d28fd..c244ed9 100644
--- a/src/bin/ui/project_common.c
+++ b/src/bin/ui/project_common.c
@@ -82,6 +82,11 @@ progress_end(void *data __UNUSED__, PM_Project_Result result)
            ERR(_("Project opening canceled."));
            break;
         }
+      case PM_PROJECT_LOCKED:
+        {
+           ERR(_("Given project file is locked."));
+           break;
+        }
       case PM_PROJECT_SUCCESS:
         {
            INFO(_("Project '%s' is opened."), ap.project->name);
diff --git a/src/bin/ui/tab_home_common.c b/src/bin/ui/tab_home_common.c
index 6d2c695..3f22bd3 100644
--- a/src/bin/ui/tab_home_common.c
+++ b/src/bin/ui/tab_home_common.c
@@ -95,6 +95,12 @@ _tabs_progress_end(void *data, PM_Project_Result result)
 {
    Meta_Data_Controls *meta = (Meta_Data_Controls *)data;
 
+   if (PM_PROJECT_LOCKED == result)
+     {
+        progress_end(data, result);
+        popup_want_action(_("File is locked"), _("File locked by another 
application"), NULL, NULL, BTN_OK, NULL, NULL);
+        return;
+     }
    if (PM_PROJECT_SUCCESS != result) return;
 
    ap.project = pm_project_thread_project_get();

-- 


Reply via email to