ecore_wayland: fix over writing file descriptor bug for reading

Summary:
fix over writing file descriptor bug for reading.
when we paste data to entry very fast, source->fd is over wrote by latest fd.
It cause blocking of read function since the read function use invalid fd.
so I make memorizing valid fd and using it in read function.

@fix

Reviewers: Hermet, jpeg, cedric, devilhorns, ManMower, raster

Differential Revision: https://phab.enlightenment.org/D4410
This commit is contained in:
Taehyub Kim 2016-11-18 19:53:14 +09:00 committed by Carsten Haitzler (Rasterman)
parent 470478030b
commit 3a98ee3796
1 changed files with 20 additions and 5 deletions

View File

@ -31,6 +31,12 @@
#include "ecore_wl_private.h"
/* local structures */
struct _dnd_source
{
Ecore_Wl_Dnd_Source *source;
int read_fd;
};
struct _dnd_task
{
void *data;
@ -615,6 +621,7 @@ _ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char *ty
struct epoll_event *ep = NULL;
struct _dnd_task *task = NULL;
struct _dnd_read_ctx *read_ctx = NULL;
struct _dnd_source *read_source = NULL;
int p[2];
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@ -640,7 +647,12 @@ _ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char *ty
epoll_fd = epoll_create1(0);
if (epoll_fd < 0) goto err;
task->data = source;
read_source = calloc(1, sizeof(struct _dnd_source));
if (!read_source) goto err;
read_source = source;
read_source->read_fd = p[0];
task->data = read_source;
task->cb = _ecore_wl_dnd_selection_data_read;
ep->events = EPOLLIN;
ep->data.ptr = task;
@ -653,7 +665,6 @@ _ecore_wl_dnd_selection_data_receive(Ecore_Wl_Dnd_Source *source, const char *ty
if (!ecore_idler_add(_ecore_wl_dnd_selection_cb_idle, read_ctx)) goto err;
source->refcount++;
source->fd = p[0];
return;
@ -661,6 +672,7 @@ err:
if (ep) free(ep);
if (task) free(task);
if (read_ctx) free(read_ctx);
if (read_source) free(read_source);
close(p[0]);
return;
}
@ -671,21 +683,23 @@ _ecore_wl_dnd_selection_data_read(void *data, Ecore_Fd_Handler *fd_handler EINA_
int len;
char buffer[PATH_MAX];
Ecore_Wl_Dnd_Source *source;
struct _dnd_source *read_source;
Ecore_Wl_Event_Selection_Data_Ready *event;
Eina_Bool ret;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
source = data;
read_source = data;
source = read_source->source;
len = read(source->fd, buffer, sizeof buffer);
len = read(read_source->read_fd, buffer, sizeof buffer);
if (!(event = calloc(1, sizeof(Ecore_Wl_Event_Selection_Data_Ready))))
return ECORE_CALLBACK_CANCEL;
if (len <= 0)
{
close(source->fd);
close(read_source->read_fd);
_ecore_wl_dnd_del(source);
event->done = EINA_TRUE;
event->data = NULL;
@ -742,6 +756,7 @@ _ecore_wl_dnd_selection_cb_idle(void *data)
if (task->cb(task->data, NULL) == ECORE_CALLBACK_CANCEL)
{
free(ctx->ep);
free(task->data);
free(task);
free(ctx);
return ECORE_CALLBACK_CANCEL;