evas and ecore_x shm segment management - fix over allocation and perms

so our sysv shm segments were both over-permissive (nothing bad
really, just other users could read and write to/from our pixel data
destined for the screen... they could do this to x11 directly anyway
so no real issue), but be more restrictive and use 0600 as xserver
runs as root so can read/write anyway and we only want our own uid
access. but even more - fix our shm segment flushing to not keep lots
of segments floating about like a bad smell when we don't need them.
we had a cache but it wasnt flushed when it should be since async
rendering turned up. this fixes that and we're back to agressively
flushing them out when idle.

@fix
This commit is contained in:
Carsten Haitzler 2016-07-26 13:18:22 +09:00
parent e2093f7886
commit 93a683daad
8 changed files with 121 additions and 30 deletions

View File

@ -621,7 +621,7 @@ _ecore_xcb_image_shm_check(void)
}
shminfo.shmid =
shmget(IPC_PRIVATE, img->stride * img->height, (IPC_CREAT | 0666));
shmget(IPC_PRIVATE, img->stride * img->height, (IPC_CREAT | 0600));
if (shminfo.shmid == (uint32_t)-1)
{
xcb_image_destroy(img);
@ -675,7 +675,7 @@ _ecore_xcb_image_shm_create(Ecore_X_Image *im)
im->depth, NULL, ~0, NULL);
if (!im->xim) return;
im->shminfo.shmid = shmget(IPC_PRIVATE, im->xim->size, (IPC_CREAT | 0666));
im->shminfo.shmid = shmget(IPC_PRIVATE, im->xim->size, (IPC_CREAT | 0600));
if (im->shminfo.shmid == (uint32_t)-1)
{
xcb_image_destroy(im->xim);

View File

@ -120,7 +120,7 @@ _ecore_x_image_shm_check(void)
}
shminfo.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height,
IPC_CREAT | 0666);
IPC_CREAT | 0600);
if (shminfo.shmid == -1)
{
ERR("%s", strerror(errno));
@ -246,7 +246,7 @@ _ecore_x_image_shm_create(Ecore_X_Image *im)
im->shminfo.shmid = shmget(IPC_PRIVATE,
im->xim->bytes_per_line * im->xim->height,
IPC_CREAT | 0666);
IPC_CREAT | 0600);
if (im->shminfo.shmid == -1)
{
ERR("shmget failed: %s", strerror(errno));

View File

@ -106,6 +106,7 @@ struct _Outbuf
/* a list of previous frame pending regions to write to the target */
Eina_List *prev_pending_writes;
Eina_Spinlock lock;
unsigned char mask_dither : 1;
unsigned char destination_alpha : 1;

View File

@ -282,7 +282,7 @@ evas_software_xcb_output_buffer_new(xcb_connection_t *conn, xcb_visualtype_t *vi
xcbob->shm_info->shmid =
shmget(IPC_PRIVATE,
xcbob->xim->stride * xcbob->xim->height,
(IPC_CREAT | 0777));
(IPC_CREAT | 0600));
if (xcbob->shm_info->shmid == (uint32_t)-1)
{
xcb_image_destroy(xcbob->xim);

View File

@ -46,6 +46,7 @@ evas_software_xcb_outbuf_init(void)
void
evas_software_xcb_outbuf_free(Outbuf *buf)
{
eina_spinlock_take(&(buf->priv.lock));
while (buf->priv.pending_writes)
{
RGBA_Image *im = NULL;
@ -67,6 +68,7 @@ evas_software_xcb_outbuf_free(Outbuf *buf)
if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
free(obr);
}
eina_spinlock_release(&(buf->priv.lock));
evas_software_xcb_outbuf_idle_flush(buf);
evas_software_xcb_outbuf_flush(buf, NULL, MODE_FULL);
@ -82,10 +84,9 @@ evas_software_xcb_outbuf_free(Outbuf *buf)
buf->priv.pal);
eina_array_flush(&buf->priv.onebuf_regions);
eina_spinlock_free(&(buf->priv.lock));
free(buf);
_clear_xcbob(EINA_FALSE);
eina_spinlock_free(&shmpool_lock);
_clear_xcbob(EINA_TRUE);
}
Outbuf *
@ -260,6 +261,7 @@ evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_co
evas_software_xcb_outbuf_drawable_set(buf, draw);
evas_software_xcb_outbuf_mask_set(buf, mask);
eina_spinlock_new(&(buf->priv.lock));
return buf;
}
@ -273,6 +275,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
Eina_Bool alpha = EINA_FALSE;
int bpl = 0;
eina_spinlock_take(&(buf->priv.lock));
if ((buf->onebuf) && (buf->priv.x11.xcb.shm))
{
Eina_Rectangle *rect;
@ -280,11 +283,15 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
if (!(obr = calloc(1, sizeof(Outbuf_Region))))
return NULL;
{
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if (!(rect = eina_rectangle_new(x, y, w, h)))
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
@ -301,6 +308,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
buf->priv.synced = EINA_TRUE;
}
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return buf->priv.onebuf;
}
obr->x = 0;
@ -330,6 +338,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
if (!obr->xcbob)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
#ifdef EVAS_CSERVE2
@ -355,6 +364,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
{
evas_software_xcb_output_buffer_free(obr->xcbob, EINA_FALSE);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->extended_info = obr;
@ -387,6 +397,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
if (!im)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
@ -423,6 +434,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
evas_cache_image_drop(&im->cache_entry);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if (buf->priv.x11.xcb.mask)
@ -441,11 +453,15 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
// memset(im->image.data, 0, (w * h * sizeof(DATA32)));
}
buf->priv.onebuf = im;
eina_spinlock_release(&(buf->priv.lock));
return im;
}
if (!(obr = calloc(1, sizeof(Outbuf_Region))))
return NULL;
{
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
obr->x = x;
obr->y = y;
@ -470,6 +486,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
if (!obr->xcbob)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
#ifdef EVAS_CSERVE2
@ -495,6 +512,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
{
_unfind_xcbob(obr->xcbob, EINA_FALSE);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->extended_info = obr;
@ -525,6 +543,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
if (!im)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
@ -558,6 +577,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
#endif
evas_cache_image_drop(&im->cache_entry);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if (buf->priv.x11.xcb.mask)
@ -577,6 +597,7 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
eina_spinlock_release(&(buf->priv.lock));
return im;
}
@ -587,14 +608,13 @@ evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_Im
}
void
evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED)
{
Eina_List *l = NULL;
RGBA_Image *im = NULL;
Outbuf_Region *obr = NULL;
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
eina_spinlock_take(&(buf->priv.lock));
if ((buf->priv.onebuf) && (eina_array_count(&buf->priv.onebuf_regions)))
{
Eina_Array_Iterator it;
@ -743,12 +763,14 @@ evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Eva
}
#endif
}
eina_spinlock_release(&(buf->priv.lock));
evas_common_cpu_end_opt();
}
void
evas_software_xcb_outbuf_idle_flush(Outbuf *buf)
{
eina_spinlock_release(&(buf->priv.lock));
if (buf->priv.onebuf)
{
RGBA_Image *im;
@ -795,6 +817,7 @@ evas_software_xcb_outbuf_idle_flush(Outbuf *buf)
}
_clear_xcbob(EINA_FALSE);
}
eina_spinlock_release(&(buf->priv.lock));
}
void
@ -807,8 +830,13 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in
int bpl = 0, yy = 0;
int bw = 0, bh = 0;
eina_spinlock_release(&(buf->priv.lock));
obr = update->extended_info;
if (!obr->xcbob) return;
if (!obr->xcbob)
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
if ((buf->rot == 0) || (buf->rot == 180))
{
@ -834,11 +862,22 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in
buf->priv.mask.g, buf->priv.mask.b,
PAL_MODE_NONE, buf->rot);
}
if (!func_conv) return;
if (!func_conv)
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
if (!(data = evas_software_xcb_output_buffer_data(obr->xcbob, &bpl)))
return;
if (!(src_data = update->image.data)) return;
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
if (!(src_data = update->image.data))
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
if (buf->rot == 0)
{
obr->x = x;
@ -965,6 +1004,7 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in
#else
xcb_flush(buf->priv.x11.xcb.conn);
#endif
eina_spinlock_release(&(buf->priv.lock));
}
void

View File

@ -288,7 +288,7 @@ evas_software_xlib_x_output_buffer_new(Display *d, Visual *v, int depth, int w,
xob->shm_info->shmid = shmget(IPC_PRIVATE,
xob->xim->bytes_per_line *
xob->xim->height,
IPC_CREAT | 0777);
IPC_CREAT | 0600);
if (xob->shm_info->shmid >= 0)
{
xob->shm_info->readOnly = False;

View File

@ -161,6 +161,7 @@ evas_software_xlib_outbuf_init(void)
void
evas_software_xlib_outbuf_free(Outbuf *buf)
{
eina_spinlock_take(&(buf->priv.lock));
while (buf->priv.pending_writes)
{
RGBA_Image *im;
@ -181,6 +182,7 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
if (obr->mxob) _unfind_xob(obr->mxob, 0);
free(obr);
}
eina_spinlock_release(&(buf->priv.lock));
evas_software_xlib_outbuf_idle_flush(buf);
evas_software_xlib_outbuf_flush(buf, NULL, EVAS_RENDER_MODE_UNDEF);
if (buf->priv.x11.xlib.gc)
@ -195,8 +197,9 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
XFreeColormap (buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap);
eina_array_flush(&buf->priv.onebuf_regions);
eina_spinlock_free(&(buf->priv.lock));
free(buf);
_clear_xob(0);
_clear_xob(1);
}
Outbuf *
@ -372,6 +375,7 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
evas_software_xlib_outbuf_drawable_set(buf, draw);
evas_software_xlib_outbuf_mask_set(buf, mask);
}
eina_spinlock_new(&(buf->priv.lock));
return buf;
}
@ -384,6 +388,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
int use_shm = 1;
int alpha;
eina_spinlock_take(&(buf->priv.lock));
if ((buf->onebuf) && (buf->priv.x11.xlib.shm))
{
Eina_Rectangle *rect;
@ -391,7 +396,11 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
rect = eina_rectangle_new(x, y, w, h);
if (!rect) return NULL;
if (!rect)
{
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if ((eina_array_push(&buf->priv.onebuf_regions, rect)) &&
(buf->priv.onebuf))
@ -405,13 +414,18 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
XSync(buf->priv.x11.xlib.disp, False);
buf->priv.synced = 1;
}
eina_spinlock_release(&(buf->priv.lock));
return buf->priv.onebuf;
}
if (rect) eina_rectangle_free(rect);
obr = calloc(1, sizeof(Outbuf_Region));
if (!obr) return NULL;
if (!obr)
{
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
obr->x = 0;
obr->y = 0;
@ -440,6 +454,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
if (!obr->xob)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
#ifdef EVAS_CSERVE2
@ -460,6 +475,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
{
evas_software_xlib_x_output_buffer_free(obr->xob, 0);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->extended_info = obr;
@ -482,6 +498,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
if (!im)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->cache_entry.flags.alpha |= alpha ? 1 : 0;
@ -511,6 +528,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
#endif
evas_cache_image_drop(&im->cache_entry);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if (buf->priv.x11.xlib.mask)
@ -539,6 +557,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
#endif
evas_cache_image_drop(&im->cache_entry);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if (buf->priv.x11.xlib.mask)
@ -558,11 +577,16 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
}
buf->priv.onebuf = im;
eina_spinlock_release(&(buf->priv.lock));
return im;
}
obr = calloc(1, sizeof(Outbuf_Region));
if (!obr) return NULL;
if (!obr)
{
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
obr->x = x;
obr->y = y;
obr->w = w;
@ -596,6 +620,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
if (!obr->xob)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
#ifdef EVAS_CSERVE2
@ -614,6 +639,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
{
_unfind_xob(obr->xob, 0);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->extended_info = obr;
@ -635,6 +661,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
if (!im)
{
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
im->cache_entry.w = w;
@ -666,6 +693,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
#endif
evas_cache_image_drop(&im->cache_entry);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if (buf->priv.x11.xlib.mask)
@ -694,6 +722,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
#endif
evas_cache_image_drop(&im->cache_entry);
free(obr);
eina_spinlock_release(&(buf->priv.lock));
return NULL;
}
if (buf->priv.x11.xlib.mask)
@ -714,6 +743,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
}
buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
eina_spinlock_release(&(buf->priv.lock));
return im;
}
@ -724,14 +754,13 @@ evas_software_xlib_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_I
}
void
evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED)
{
Eina_List *l;
RGBA_Image *im;
Outbuf_Region *obr;
if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return;
eina_spinlock_take(&(buf->priv.lock));
if ((buf->priv.onebuf) && eina_array_count(&buf->priv.onebuf_regions))
{
Eina_Rectangle *rect;
@ -890,12 +919,14 @@ evas_software_xlib_outbuf_flush(Outbuf *buf, Tilebuf_Rect *rects EINA_UNUSED, Ev
}
#endif
}
eina_spinlock_release(&(buf->priv.lock));
evas_common_cpu_end_opt();
}
void
evas_software_xlib_outbuf_idle_flush(Outbuf *buf)
{
eina_spinlock_take(&(buf->priv.lock));
if (buf->priv.onebuf)
{
RGBA_Image *im;
@ -943,6 +974,7 @@ evas_software_xlib_outbuf_idle_flush(Outbuf *buf)
}
_clear_xob(0);
}
eina_spinlock_release(&(buf->priv.lock));
}
void
@ -954,6 +986,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
unsigned char *data;
int bpl = 0, yy;
eina_spinlock_take(&(buf->priv.lock));
obr = update->extended_info;
if (buf->priv.pal)
{
@ -985,13 +1018,29 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
buf->priv.mask.g, buf->priv.mask.b,
PAL_MODE_NONE, buf->rot);
}
if (!conv_func) return;
if (!conv_func)
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
if (!obr->xob) return;
if (!obr->xob)
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
data = evas_software_xlib_x_output_buffer_data(obr->xob, &bpl);
if (!data) return;
if (!data)
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
src_data = update->image.data;
if (!src_data) return;
if (!src_data)
{
eina_spinlock_release(&(buf->priv.lock));
return;
}
if (buf->rot == 0)
{
obr->x = x;
@ -1125,6 +1174,7 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
#else
XFlush(buf->priv.x11.xlib.disp);
#endif
eina_spinlock_release(&(buf->priv.lock));
}
void

View File

@ -59,7 +59,7 @@ _buf_new(X_Swapper *swp, Buffer *buf)
buf->bpl = buf->xim->bytes_per_line;
buf->shm_info.shmid = shmget(IPC_PRIVATE, buf->bpl * buf->h,
IPC_CREAT | 0777);
IPC_CREAT | 0600);
if (buf->shm_info.shmid >= 0)
{
buf->shm_info.readOnly = False;