diff options
Diffstat (limited to 'xorg-server/Xext')
-rwxr-xr-x[-rw-r--r--] | xorg-server/Xext/shm.c | 168 | ||||
-rw-r--r-- | xorg-server/Xext/shmint.h | 10 | ||||
-rw-r--r-- | xorg-server/Xext/sync.c | 43 | ||||
-rw-r--r-- | xorg-server/Xext/syncsrv.h | 13 | ||||
-rw-r--r-- | xorg-server/Xext/xvdisp.c | 13 |
5 files changed, 220 insertions, 27 deletions
diff --git a/xorg-server/Xext/shm.c b/xorg-server/Xext/shm.c index 37c1ed88f..0bf27f4c6 100644..100755 --- a/xorg-server/Xext/shm.c +++ b/xorg-server/Xext/shm.c @@ -55,6 +55,7 @@ in this Software without prior written authorization from The Open Group. #include "xace.h" #include <X11/extensions/shmproto.h> #include <X11/Xfuncproto.h> +#include <sys/mman.h> #include "protocol-versions.h" /* Needed for Solaris cross-zone shared memory extension */ @@ -91,15 +92,6 @@ in this Software without prior written authorization from The Open Group. #include "extinit.h" -typedef struct _ShmDesc { - struct _ShmDesc *next; - int shmid; - int refcnt; - char *addr; - Bool writable; - unsigned long size; -} ShmDescRec, *ShmDescPtr; - typedef struct _ShmScrPrivateRec { CloseScreenProcPtr CloseScreen; ShmFuncsPtr shmFuncs; @@ -408,8 +400,10 @@ ProcShmAttach(ClientPtr client) client->errorValue = stuff->readOnly; return BadValue; } - for (shmdesc = Shmsegs; - shmdesc && (shmdesc->shmid != stuff->shmid); shmdesc = shmdesc->next); + for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next) { + if (!shmdesc->is_fd && shmdesc->shmid == stuff->shmid) + break; + } if (shmdesc) { if (!stuff->readOnly && !shmdesc->writable) return BadAccess; @@ -419,6 +413,7 @@ ProcShmAttach(ClientPtr client) shmdesc = malloc(sizeof(ShmDescRec)); if (!shmdesc) return BadAlloc; + shmdesc->is_fd = FALSE; shmdesc->addr = shmat(stuff->shmid, 0, stuff->readOnly ? SHM_RDONLY : 0); if ((shmdesc->addr == ((char *) -1)) || SHMSTAT(stuff->shmid, &buf)) { @@ -458,7 +453,10 @@ ShmDetachSegment(pointer value, /* must conform to DeleteType */ if (--shmdesc->refcnt) return TRUE; #ifndef _MSC_VER - shmdt(shmdesc->addr); + if (shmdesc->is_fd) + munmap(shmdesc->addr, shmdesc->size); + else + shmdt(shmdesc->addr); #endif for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next); *prev = shmdesc->next; @@ -1116,6 +1114,122 @@ ProcShmCreatePixmap(ClientPtr client) } static int +ProcShmAttachFd(ClientPtr client) +{ + int fd; + ShmDescPtr shmdesc; + REQUEST(xShmAttachFdReq); + struct stat statb; + + SetReqFds(client, 1); + REQUEST_SIZE_MATCH(xShmAttachFdReq); + LEGAL_NEW_RESOURCE(stuff->shmseg, client); + if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) { + client->errorValue = stuff->readOnly; + return BadValue; + } + fd = ReadFdFromClient(client); + if (fd < 0) + return BadMatch; + + if (fstat(fd, &statb) < 0 || statb.st_size == 0) { + close(fd); + return BadMatch; + } + + shmdesc = malloc(sizeof(ShmDescRec)); + if (!shmdesc) { + close(fd); + return BadAlloc; + } + shmdesc->is_fd = TRUE; + shmdesc->addr = mmap(NULL, statb.st_size, + stuff->readOnly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, + fd, 0); + + close(fd); + if ((shmdesc->addr == ((char *) -1))) { + free(shmdesc); + return BadAccess; + } + + shmdesc->refcnt = 1; + shmdesc->writable = !stuff->readOnly; + shmdesc->size = statb.st_size; + shmdesc->next = Shmsegs; + Shmsegs = shmdesc; + + if (!AddResource(stuff->shmseg, ShmSegType, (pointer) shmdesc)) + return BadAlloc; + return Success; +} + +static int +ProcShmCreateSegment(ClientPtr client) +{ + int fd; + ShmDescPtr shmdesc; + REQUEST(xShmCreateSegmentReq); + xShmCreateSegmentReply rep = { + .type = X_Reply, + .nfd = 1, + .sequenceNumber = client->sequence, + .length = 0, + }; + char template[] = "/tmp/shm-XXXXXX"; + + REQUEST_SIZE_MATCH(xShmCreateSegmentReq); + if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) { + client->errorValue = stuff->readOnly; + return BadValue; + } + fd = mkstemp(template); + if (fd < 0) + return BadAlloc; + unlink(template); + if (ftruncate(fd, stuff->size) < 0) { + close(fd); + return BadAlloc; + } + shmdesc = malloc(sizeof(ShmDescRec)); + if (!shmdesc) { + close(fd); + return BadAlloc; + } + shmdesc->is_fd = TRUE; + shmdesc->addr = mmap(NULL, stuff->size, + stuff->readOnly ? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED, + fd, 0); + + if ((shmdesc->addr == ((char *) -1))) { + close(fd); + free(shmdesc); + return BadAccess; + } + + shmdesc->refcnt = 1; + shmdesc->writable = !stuff->readOnly; + shmdesc->size = stuff->size; + shmdesc->next = Shmsegs; + Shmsegs = shmdesc; + + if (!AddResource(stuff->shmseg, ShmSegType, (pointer) shmdesc)) { + close(fd); + return BadAlloc; + } + + if (WriteFdToClient(client, fd, TRUE) < 0) { + FreeResource(stuff->shmseg, RT_NONE); + close(fd); + return BadAlloc; + } + WriteToClient(client, sizeof (xShmCreateSegmentReply), &rep); + return Success; +} + +static int ProcShmDispatch(ClientPtr client) { REQUEST(xReq); @@ -1144,6 +1258,10 @@ ProcShmDispatch(ClientPtr client) return ProcPanoramiXShmCreatePixmap(client); #endif return ProcShmCreatePixmap(client); + case X_ShmAttachFd: + return ProcShmAttachFd(client); + case X_ShmCreateSegment: + return ProcShmCreateSegment(client); default: return BadRequest; } @@ -1245,6 +1363,28 @@ SProcShmCreatePixmap(ClientPtr client) } static int +SProcShmAttachFd(ClientPtr client) +{ + REQUEST(xShmAttachFdReq); + SetReqFds(client, 1); + swaps(&stuff->length); + REQUEST_SIZE_MATCH(xShmAttachFdReq); + swapl(&stuff->shmseg); + return ProcShmAttachFd(client); +} + +static int +SProcShmCreateSegment(ClientPtr client) +{ + REQUEST(xShmCreateSegmentReq); + swaps(&stuff->length); + REQUEST_SIZE_MATCH(xShmCreateSegmentReq); + swapl(&stuff->shmseg); + swapl(&stuff->size); + return ProcShmCreateSegment(client); +} + +static int SProcShmDispatch(ClientPtr client) { REQUEST(xReq); @@ -1261,6 +1401,10 @@ SProcShmDispatch(ClientPtr client) return SProcShmGetImage(client); case X_ShmCreatePixmap: return SProcShmCreatePixmap(client); + case X_ShmAttachFd: + return SProcShmAttachFd(client); + case X_ShmCreateSegment: + return SProcShmCreateSegment(client); default: return BadRequest; } diff --git a/xorg-server/Xext/shmint.h b/xorg-server/Xext/shmint.h index fa6941c90..db35fbbbe 100644 --- a/xorg-server/Xext/shmint.h +++ b/xorg-server/Xext/shmint.h @@ -56,6 +56,16 @@ typedef struct _ShmFuncs { void (*PutImage) (XSHM_PUT_IMAGE_ARGS); } ShmFuncs, *ShmFuncsPtr; +typedef struct _ShmDesc { + struct _ShmDesc *next; + int shmid; + int refcnt; + char *addr; + Bool is_fd; + Bool writable; + unsigned long size; +} ShmDescRec, *ShmDescPtr; + extern _X_EXPORT void ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs); diff --git a/xorg-server/Xext/sync.c b/xorg-server/Xext/sync.c index 80190f0f0..b956c9ec8 100644 --- a/xorg-server/Xext/sync.c +++ b/xorg-server/Xext/sync.c @@ -141,7 +141,7 @@ SyncCheckWarnIsCounter(const SyncObject * pSync, const char *warning) * interested in the counter. The two functions below are used to * delete and add triggers on this list. */ -static void +void SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger) { SyncTriggerList *pCur; @@ -184,7 +184,7 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger) } } -static int +int SyncAddTriggerToSyncObject(SyncTrigger * pTrigger) { SyncTriggerList *pCur; @@ -914,6 +914,34 @@ SyncCreate(ClientPtr client, XID id, unsigned char type) return pSync; } +int +SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL initially_triggered) +{ + SyncFence *pFence; + int status; + + pFence = (SyncFence *) SyncCreate(client, id, SYNC_FENCE); + if (!pFence) + return BadAlloc; + + status = miSyncInitFenceFromFD(pDraw, pFence, fd, initially_triggered); + if (status != Success) { + miSyncDestroyFence(pFence); + return status; + } + + if (!AddResource(id, RTFence, (pointer) pFence)) + return BadAlloc; + + return Success; +} + +int +SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *pFence) +{ + return miSyncFDFromFence(pDraw, pFence); +} + static SyncCounter * SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue) { @@ -2653,7 +2681,16 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa IdleTimeQueryValue(counter, &idle); counter->value = idle; /* push, so CheckTrigger works */ - if (less && XSyncValueLessOrEqual(idle, *less)) { + /** + * There's an indefinite amount of time between ProcessInputEvents() + * where the idle time is reset and the time we actually get here. idle + * may be past the lower bracket if we dawdled with the events, so + * check for whether we did reset and bomb out of select immediately. + */ + if (less && XSyncValueGreaterThan(idle, *less) && + LastEventTimeWasReset(priv->deviceid)) { + AdjustWaitForDelay(wt, 0); + } else if (less && XSyncValueLessOrEqual(idle, *less)) { /* * We've been idle for less than the threshold value, and someone * wants to know about that, but now we need to know whether they diff --git a/xorg-server/Xext/syncsrv.h b/xorg-server/Xext/syncsrv.h index c68229f46..45fca04da 100644 --- a/xorg-server/Xext/syncsrv.h +++ b/xorg-server/Xext/syncsrv.h @@ -136,4 +136,17 @@ extern void SyncDestroySystemCounter(pointer pCounter); extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev); extern void SyncRemoveDeviceIdleTime(SyncCounter *counter); + +int +SyncCreateFenceFromFD(ClientPtr client, DrawablePtr pDraw, XID id, int fd, BOOL initially_triggered); + +int +SyncFDFromFence(ClientPtr client, DrawablePtr pDraw, SyncFence *fence); + +void +SyncDeleteTriggerFromSyncObject(SyncTrigger * pTrigger); + +int +SyncAddTriggerToSyncObject(SyncTrigger * pTrigger); + #endif /* _SYNCSRV_H_ */ diff --git a/xorg-server/Xext/xvdisp.c b/xorg-server/Xext/xvdisp.c index 787729387..613867a6b 100644 --- a/xorg-server/Xext/xvdisp.c +++ b/xorg-server/Xext/xvdisp.c @@ -43,6 +43,7 @@ SOFTWARE. #include "xvdix.h" #ifdef MITSHM #include <X11/extensions/shmproto.h> +#include "shmint.h" #endif #include "xvdisp.h" @@ -949,18 +950,6 @@ ProcXvPutImage(ClientPtr client) } #ifdef MITSHM -/* redefined here since it's not in any header file */ -typedef struct _ShmDesc { - struct _ShmDesc *next; - int shmid; - int refcnt; - char *addr; - Bool writable; - unsigned long size; -} ShmDescRec, *ShmDescPtr; - -extern RESTYPE ShmSegType; -extern int ShmCompletionCode; static int ProcXvShmPutImage(ClientPtr client) |