aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xext
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xext')
-rwxr-xr-x[-rw-r--r--]xorg-server/Xext/shm.c168
-rw-r--r--xorg-server/Xext/shmint.h10
-rw-r--r--xorg-server/Xext/sync.c43
-rw-r--r--xorg-server/Xext/syncsrv.h13
-rw-r--r--xorg-server/Xext/xvdisp.c13
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)