struct _Shmfile
{
- int fd;
+ void *addr, *addr2;
+ const char *file, *file2;
+ int fd, fd2;
int size;
- void *addr;
- const char *file;
};
static int blank = 0x00000000;
shmfile_new(const char *base, int id, int size, Eina_Bool sys)
{
Shmfile *sf;
- char file[PATH_MAX];
+ char file[PATH_MAX], file2[PATH_MAX];
sf = calloc(1, sizeof(Shmfile));
+ if (!sf) return NULL;
+ sf->fd = -1;
+ sf->fd2 = -1;
+ sf->addr = MAP_FAILED;
+ sf->addr = MAP_FAILED;
do
{
mode_t mode;
+ int v1, v2, v3;
- snprintf(file, sizeof(file), "/%s-%i-%i.%i.%i",
- base, id, (int)time(NULL), (int)getpid(), (int)rand());
+ v1 = (int)time(NULL);
+ v2 = (int)getpid();
+ v3 = (int)rand();
mode = S_IRUSR | S_IWUSR;
if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ snprintf(file, sizeof(file), "/%s-%i-%i.%i.%i", base, id, v1, v2, v3);
sf->fd = shm_open(file, O_RDWR | O_CREAT | O_EXCL, mode);
+ if (sf->fd >= 0)
+ {
+ snprintf(file2, sizeof(file2), "/%s-%i-%i.%i.%i-b", base, id, v1, v2, v3);
+ sf->fd2 = shm_open(file2, O_RDWR | O_CREAT | O_EXCL, mode);
+ if (sf->fd2 < 0)
+ {
+ close(sf->fd);
+ sf->fd = -1;
+ }
+ }
}
while (sf->fd < 0);
sf->file = eina_stringshare_add(file);
- if (!sf->file)
- {
- close(sf->fd);
- shm_unlink(sf->file);
- eina_stringshare_del(sf->file);
- free(sf);
- return NULL;
- }
+ if (!sf->file) goto err;
+ sf->file2 = eina_stringshare_add(file2);
+ if (!sf->file2) goto err;
sf->size = size;
- if (ftruncate(sf->fd, size) < 0)
+ if (ftruncate(sf->fd, size) < 0) goto err;
+ if (ftruncate(sf->fd2, size) < 0) goto err;
+ sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0);
+ if (sf->addr == MAP_FAILED) goto err;
+ sf->addr2 = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd2, 0);
+ if (sf->addr2 == MAP_FAILED) goto err;
+ return sf;
+err:
+ if (sf->addr != MAP_FAILED) munmap(sf->addr, sf->size);
+ if (sf->addr2 != MAP_FAILED) munmap(sf->addr2, sf->size);
+ if (sf->fd >= 0)
{
close(sf->fd);
- shm_unlink(sf->file);
- eina_stringshare_del(sf->file);
- free(sf);
- return NULL;
+ shm_unlink(file);
}
- sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0);
- if (sf->addr == MAP_FAILED)
+ if (sf->fd2 >= 0)
{
- close(sf->fd);
- shm_unlink(sf->file);
- eina_stringshare_del(sf->file);
- free(sf);
- return NULL;
+ close(sf->fd2);
+ shm_unlink(file2);
}
- return sf;
+ if (sf->file) eina_stringshare_del(sf->file);
+ if (sf->file2) eina_stringshare_del(sf->file2);
+ free(sf);
+ return NULL;
}
void
shmfile_free(Shmfile *sf)
{
munmap(sf->addr, sf->size);
+ munmap(sf->addr2, sf->size);
close(sf->fd);
+ close(sf->fd2);
shm_unlink(sf->file);
+ shm_unlink(sf->file2);
eina_stringshare_del(sf->file);
+ eina_stringshare_del(sf->file2);
free(sf);
}
{
Shmfile *sf;
mode_t mode;
-
+ char *s;
+ int l;
+
sf = calloc(1, sizeof(Shmfile));
+ if (!sf) return NULL;
+ sf->fd = -1;
+ sf->fd2 = -1;
+ sf->addr = MAP_FAILED;
+ sf->addr = MAP_FAILED;
mode = S_IRUSR | S_IWUSR;
if (sys) mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
- sf->fd = shm_open(ref, O_RDWR, mode);
- if (sf->fd < 0)
- {
- free(sf);
- return NULL;
- }
+ l = strlen(ref);
+ s = alloca(l + 3);
+ strcpy(s, ref);
+ s[l] = '-';
+ s[l + 1] = 'b';
+ s[l + 2] = 0;
sf->file = eina_stringshare_add(ref);
- if (!sf->file)
- {
- close(sf->fd);
- eina_stringshare_del(sf->file);
- free(sf);
- return NULL;
- }
+ if (!sf->file) goto err;
+ sf->file2 = eina_stringshare_add(s);
+ if (!sf->file2) goto err;
+ sf->fd = shm_open(sf->file, O_RDWR, mode);
+ if (sf->fd < 0) goto err;
+ sf->fd2 = shm_open(sf->file2, O_RDWR, mode);
+ if (sf->fd2 < 0) goto err;
sf->size = size;
sf->addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd, 0);
- if (sf->addr == MAP_FAILED)
- {
- close(sf->fd);
- eina_stringshare_del(sf->file);
- free(sf);
- return NULL;
- }
+ if (sf->addr == MAP_FAILED) goto err;
+ sf->addr2 = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, sf->fd2, 0);
+ if (sf->addr2 == MAP_FAILED) goto err;
return sf;
+err:
+ if (sf->addr != MAP_FAILED) munmap(sf->addr, sf->size);
+ if (sf->addr2 != MAP_FAILED) munmap(sf->addr2, sf->size);
+ if (sf->fd >= 0) close(sf->fd);
+ if (sf->fd2 >= 0) close(sf->fd2);
+ if (sf->file) eina_stringshare_del(sf->file);
+ if (sf->file2) eina_stringshare_del(sf->file2);
+ free(sf);
+ return NULL;
}
void
shmfile_close(Shmfile *sf)
{
munmap(sf->addr, sf->size);
+ munmap(sf->addr2, sf->size);
close(sf->fd);
+ close(sf->fd2);
eina_stringshare_del(sf->file);
+ eina_stringshare_del(sf->file2);
free(sf);
}
OP_EV_MULTI_MOVE,
OP_EV_KEY_UP,
OP_EV_KEY_DOWN,
- OP_EV_HOLD
+ OP_EV_HOLD,
+ OP_LOCK_FILE2
};
enum
Eina_Bool sys : 1;
} svc;
struct {
- const char *lock;
- int lockfd;
+ const char *lock, *lock2;
+ int lockfd, lockfd2;
const char *shm;
int w, h;
Shmfile *shmfile;
Eina_List *updates;
Eina_Bool have_lock : 1;
Eina_Bool have_real_lock : 1;
+ Eina_Bool have_lock2 : 1;
+ Eina_Bool have_real_lock2 : 1;
} file;
struct {
Eina_Bool done : 1; /* need to send change done event to the client(plug) */
}
static Eina_Bool
-_ecore_evas_lock_other_have(Ecore_Evas *ee)
+_ecore_evas_lock_other_have(Ecore_Evas *ee, int buf)
{
Eina_List *l;
Ecore_Evas *ee2;
bdata2 = ee2->engine.data;
extn2 = bdata2->data;
if (!extn2) continue;
- if ((extn->file.lock) && (extn2->file.lock) &&
- (!strcmp(extn->file.lock, extn2->file.lock)) &&
- (extn2->file.have_real_lock))
- return EINA_TRUE;
+ if (buf == 0)
+ {
+ if ((extn->file.lock) && (extn2->file.lock) &&
+ (!strcmp(extn->file.lock, extn2->file.lock)) &&
+ (extn2->file.have_real_lock))
+ return EINA_TRUE;
+ }
+ else if (buf == 1)
+ {
+ if ((extn->file.lock2) && (extn2->file.lock2) &&
+ (!strcmp(extn->file.lock2, extn2->file.lock2)) &&
+ (extn2->file.have_real_lock2))
+ return EINA_TRUE;
+ }
}
return EINA_FALSE;
}
static void
-_ecore_evas_socket_lock(Ecore_Evas *ee)
+_ecore_evas_socket_lock(Ecore_Evas *ee, int buf)
{
Extn *extn;
Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data;
extn = bdata->data;
if (!extn) return;
- if (extn->file.lockfd < 0) return;
- if (extn->file.have_lock) return;
- extn->file.have_lock = EINA_TRUE;
- if (_ecore_evas_lock_other_have(ee)) return;
- lockf(extn->file.lockfd, F_ULOCK, 0);
- extn->file.have_real_lock = EINA_TRUE;
+ if (buf == 0)
+ {
+ if (extn->file.lockfd < 0) return;
+ if (extn->file.have_lock) return;
+ extn->file.have_lock = EINA_TRUE;
+ if (_ecore_evas_lock_other_have(ee, buf)) return;
+ if (lockf(extn->file.lockfd, F_ULOCK, 0) < 0)
+ {
+ extn->file.have_lock = EINA_FALSE;
+ return;
+ }
+ extn->file.have_real_lock = EINA_TRUE;
+ }
+ else if (buf == 1)
+ {
+ if (extn->file.lockfd2 < 0) return;
+ if (extn->file.have_lock2) return;
+ extn->file.have_lock2 = EINA_TRUE;
+ if (_ecore_evas_lock_other_have(ee, buf)) return;
+ if (lockf(extn->file.lockfd2, F_ULOCK, 0) < 0)
+ {
+ extn->file.have_lock2 = EINA_FALSE;
+ return;
+ }
+ extn->file.have_real_lock2 = EINA_TRUE;
+ }
}
static void
-_ecore_evas_socket_unlock(Ecore_Evas *ee)
+_ecore_evas_socket_unlock(Ecore_Evas *ee, int buf)
{
Extn *extn;
Ecore_Evas_Engine_Buffer_Data *bdata = ee->engine.data;
extn = bdata->data;
if (!extn) return;
- if (extn->file.lockfd < 0) return;
- if (!extn->file.have_lock) return;
- extn->file.have_lock = EINA_FALSE;
- if (!extn->file.have_real_lock) return;
- lockf(extn->file.lockfd, F_ULOCK, 0);
+ if (buf == 0)
+ {
+ if (extn->file.lockfd < 0) return;
+ if (!extn->file.have_lock) return;
+ extn->file.have_lock = EINA_FALSE;
+ if (!extn->file.have_real_lock) return;
+ if (lockf(extn->file.lockfd, F_ULOCK, 0) < 0) return;
+ }
+ else if (buf == 1)
+ {
+ if (extn->file.lockfd2 < 0) return;
+ if (!extn->file.have_lock2) return;
+ extn->file.have_lock2 = EINA_FALSE;
+ if (!extn->file.have_real_lock2) return;
+ if (lockf(extn->file.lockfd2, F_ULOCK, 0) < 0) return;
+ }
}
static void
_ecore_evas_extn_plug_targer_render_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
Ecore_Evas *ee = data;
- if (ee) _ecore_evas_socket_lock(ee);
+ if (ee) _ecore_evas_socket_lock(ee, 0); // XXX choose right buffer to lock
}
static void
_ecore_evas_extn_plug_targer_render_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
{
Ecore_Evas *ee = data;
- if (ee) _ecore_evas_socket_unlock(ee);
+ if (ee) _ecore_evas_socket_unlock(ee, 0); // XXX choose right buffer to lock
}
static void
{
Ecore_Event_Handler *hdl;
- if (extn->file.have_lock)
- _ecore_evas_socket_unlock(ee);
- if (extn->file.lockfd)
+ if (extn->file.have_lock) _ecore_evas_socket_unlock(ee, 0);
+ if (extn->file.have_lock2) _ecore_evas_socket_unlock(ee, 1);
+ if (extn->file.lockfd >= 0)
{
close(extn->file.lockfd);
if (extn->ipc.am_server)
if (extn->file.lock) unlink(extn->file.lock);
}
}
+ if (extn->file.lockfd2 >= 0)
+ {
+ close(extn->file.lockfd2);
+ if (extn->ipc.am_server)
+ {
+ if (extn->file.lock2) unlink(extn->file.lock2);
+ }
+ }
if (extn->svc.name) eina_stringshare_del(extn->svc.name);
if (extn->ipc.clients)
{
}
if (extn->ipc.server) ecore_ipc_server_del(extn->ipc.server);
if (extn->file.lock) eina_stringshare_del(extn->file.lock);
+ if (extn->file.lock2) eina_stringshare_del(extn->file.lock2);
if (extn->file.shm) eina_stringshare_del(extn->file.shm);
if (extn->file.shmfile)
{
if ((e->data) && (e->size > 0) &&
(((unsigned char *)e->data)[e->size - 1] == 0))
{
- if (extn->file.have_lock) _ecore_evas_socket_unlock(ee);
+ if (extn->file.have_lock) _ecore_evas_socket_unlock(ee, 0);
if (extn->file.lockfd) close(extn->file.lockfd);
if (extn->file.lock) eina_stringshare_del(extn->file.lock);
extn->file.lock = eina_stringshare_add(e->data);
extn->file.lockfd = open(extn->file.lock, O_RDONLY);
}
break;
+ case OP_LOCK_FILE2:
+ if ((e->data) && (e->size > 0) &&
+ (((unsigned char *)e->data)[e->size - 1] == 0))
+ {
+ if (extn->file.have_lock2) _ecore_evas_socket_unlock(ee, 1);
+ if (extn->file.lockfd2 >= 0) close(extn->file.lockfd2);
+ if (extn->file.lock2) eina_stringshare_del(extn->file.lock2);
+ extn->file.lock2 = eina_stringshare_add(e->data);
+ extn->file.lockfd2 = open(extn->file.lock2, O_RDONLY);
+ }
+ break;
case OP_SHM_REF:
// e->ref == w
// e->ref_to == h
_ecore_evas_extn_plug_object_data_lock(Ecore_Evas *ee)
{
if (!ee) return;
- _ecore_evas_socket_lock(ee);
+ _ecore_evas_socket_lock(ee, 0); // XXX lock correct buffer
}
static void
_ecore_evas_extn_plug_object_data_unlock(Ecore_Evas *ee)
{
if (!ee) return;
- _ecore_evas_socket_unlock(ee);
+ _ecore_evas_socket_unlock(ee, 0); // XXX lock correct buffer
}
static void
if (bdata->pixels)
{
- _ecore_evas_socket_lock(ee);
+ _ecore_evas_socket_lock(ee, 0); // XXX lock correct buffer
updates = evas_render_updates(ee->evas);
- _ecore_evas_socket_unlock(ee);
+ _ecore_evas_socket_unlock(ee, 0); // XXX lock correct buffer
}
EINA_LIST_FOREACH(updates, l, r)
{
extn->ipc.clients = eina_list_append(extn->ipc.clients, e->client);
ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE, 0, 0, 0, extn->file.lock, strlen(extn->file.lock) + 1);
+ ecore_ipc_client_send(e->client, MAJOR, OP_LOCK_FILE2, 0, 0, 0, extn->file.lock2, strlen(extn->file.lock2) + 1);
if (extn->file.shmfile)
{
{
if (extn->file.lockfd)
{
- close(extn->file.lockfd);
+ close(extn->file.lockfd >= 0);
unlink(buf);
}
eina_stringshare_del(extn->svc.name);
return EINA_FALSE;
}
+ snprintf(buf, sizeof(buf), "/tmp/ee-lock-XXXXXX");
+ extn->file.lockfd2 = mkstemp(buf);
+ if (extn->file.lockfd2 >= 0)
+ extn->file.lock2 = eina_stringshare_add(buf);
+ if ((extn->file.lockfd2 < 0) || (!extn->file.lock2))
+ {
+ if (extn->file.lockfd >= 0)
+ {
+ close(extn->file.lockfd);
+ if (extn->file.lock) unlink(extn->file.lock);
+ }
+ if (extn->file.lockfd2 >= 0)
+ {
+ close(extn->file.lockfd2);
+ unlink(buf);
+ }
+ eina_stringshare_del(extn->svc.name);
+ if (extn->file.lock) eina_stringshare_del(extn->file.lock);
+ if (extn->file.lock2) eina_stringshare_del(extn->file.lock2);
+ free(extn);
+ ecore_ipc_shutdown();
+ return EINA_FALSE;
+ }
+
if (extn->svc.sys) ipctype = ECORE_IPC_LOCAL_SYSTEM;
extn->ipc.am_server = EINA_TRUE;
extn->ipc.server = ecore_ipc_server_add(ipctype,
extn->svc.num, ee);
if (!extn->ipc.server)
{
- if (extn->file.lockfd)
+ if (extn->file.lockfd >= 0)
{
close(extn->file.lockfd);
if (extn->file.lock) unlink(extn->file.lock);
}
+ if (extn->file.lockfd2 >= 0)
+ {
+ close(extn->file.lockfd2);
+ if (extn->file.lock2) unlink(extn->file.lock2);
+ }
eina_stringshare_del(extn->svc.name);
eina_stringshare_del(extn->file.lock);
+ eina_stringshare_del(extn->file.lock2);
free(extn);
ecore_ipc_shutdown();
return EINA_FALSE;