(submit/recv-fds) os: read file descriptors into client struct at once
Instead of having the request handler ask for fd's one by one, just read them all into a little array in ClientRec struct. And also automatically clean up after request had been handled. Request handlers need to set the entries to -1 if they shouldn't be closed automatically. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
parent
b487d2d77f
commit
2e847c7b23
|
@ -1151,14 +1151,15 @@ ProcShmAttachFd(ClientPtr client)
|
||||||
REQUEST(xShmAttachFdReq);
|
REQUEST(xShmAttachFdReq);
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
|
|
||||||
SetReqFds(client, 1);
|
|
||||||
REQUEST_SIZE_MATCH(xShmAttachFdReq);
|
REQUEST_SIZE_MATCH(xShmAttachFdReq);
|
||||||
LEGAL_NEW_RESOURCE(stuff->shmseg, client);
|
LEGAL_NEW_RESOURCE(stuff->shmseg, client);
|
||||||
if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) {
|
if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) {
|
||||||
client->errorValue = stuff->readOnly;
|
client->errorValue = stuff->readOnly;
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
fd = ReadFdFromClient(client);
|
fd = client->recv_fd_list[0];
|
||||||
|
client->recv_fd_list[0] = -1;
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return BadMatch;
|
return BadMatch;
|
||||||
|
|
||||||
|
@ -1462,7 +1463,6 @@ static int _X_COLD
|
||||||
SProcShmAttachFd(ClientPtr client)
|
SProcShmAttachFd(ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xShmAttachFdReq);
|
REQUEST(xShmAttachFdReq);
|
||||||
SetReqFds(client, 1);
|
|
||||||
REQUEST_SIZE_MATCH(xShmAttachFdReq);
|
REQUEST_SIZE_MATCH(xShmAttachFdReq);
|
||||||
swapl(&stuff->shmseg);
|
swapl(&stuff->shmseg);
|
||||||
return ProcShmAttachFd(client);
|
return ProcShmAttachFd(client);
|
||||||
|
|
|
@ -562,6 +562,14 @@ Dispatch(void)
|
||||||
(*client->requestVector[client->majorOp]) (client);
|
(*client->requestVector[client->majorOp]) (client);
|
||||||
currentClient = NULL;
|
currentClient = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if XTRANS_SEND_FDS
|
||||||
|
/* close down all unused passed fd's */
|
||||||
|
for (int x=0; x<MAX_CLIENT_RECV_FD; x++) {
|
||||||
|
close(client->recv_fd_list[x]);
|
||||||
|
client->recv_fd_list[x] = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (!SmartScheduleSignalEnable)
|
if (!SmartScheduleSignalEnable)
|
||||||
SmartScheduleTime = GetTimeInMillis();
|
SmartScheduleTime = GetTimeInMillis();
|
||||||
|
|
|
@ -16,13 +16,6 @@
|
||||||
#include "dixstruct.h"
|
#include "dixstruct.h"
|
||||||
#include <X11/Xmd.h>
|
#include <X11/Xmd.h>
|
||||||
|
|
||||||
static inline void
|
|
||||||
SetReqFds(ClientPtr client, int req_fds) {
|
|
||||||
if (client->req_fds != 0 && req_fds != client->req_fds)
|
|
||||||
LogMessage(X_ERROR, "Mismatching number of request fds %d != %d\n", req_fds, client->req_fds);
|
|
||||||
client->req_fds = req_fds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scheduling interface
|
* Scheduling interface
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -191,7 +191,6 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
|
||||||
CARD32 stride, offset;
|
CARD32 stride, offset;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
SetReqFds(client, 1);
|
|
||||||
REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
|
REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
|
||||||
LEGAL_NEW_RESOURCE(stuff->pixmap, client);
|
LEGAL_NEW_RESOURCE(stuff->pixmap, client);
|
||||||
rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
|
rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
|
||||||
|
@ -220,7 +219,8 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = ReadFdFromClient(client);
|
fd = client->recv_fd_list[0];
|
||||||
|
client->recv_fd_list[0] = -1;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
|
@ -309,7 +309,6 @@ proc_dri3_fence_from_fd(ClientPtr client)
|
||||||
int fd;
|
int fd;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
SetReqFds(client, 1);
|
|
||||||
REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
|
REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
|
||||||
LEGAL_NEW_RESOURCE(stuff->fence, client);
|
LEGAL_NEW_RESOURCE(stuff->fence, client);
|
||||||
|
|
||||||
|
@ -317,7 +316,8 @@ proc_dri3_fence_from_fd(ClientPtr client)
|
||||||
if (status != Success)
|
if (status != Success)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
fd = ReadFdFromClient(client);
|
fd = client->recv_fd_list[0];
|
||||||
|
client->recv_fd_list[0] = -1;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
|
@ -434,7 +434,6 @@ proc_dri3_pixmap_from_buffers(ClientPtr client)
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
SetReqFds(client, stuff->num_buffers);
|
|
||||||
REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
|
REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
|
||||||
LEGAL_NEW_RESOURCE(stuff->pixmap, client);
|
LEGAL_NEW_RESOURCE(stuff->pixmap, client);
|
||||||
rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
|
rc = dixLookupWindow(&window, stuff->window, client, DixGetAttrAccess);
|
||||||
|
@ -470,7 +469,7 @@ proc_dri3_pixmap_from_buffers(ClientPtr client)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < stuff->num_buffers; i++) {
|
for (i = 0; i < stuff->num_buffers; i++) {
|
||||||
fds[i] = ReadFdFromClient(client);
|
fds[i] = client->recv_fd_list[i];
|
||||||
if (fds[i] < 0) {
|
if (fds[i] < 0) {
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
close(fds[i]);
|
close(fds[i]);
|
||||||
|
@ -609,7 +608,6 @@ proc_dri3_import_syncobj(ClientPtr client)
|
||||||
int fd;
|
int fd;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
SetReqFds(client, 1);
|
|
||||||
REQUEST_SIZE_MATCH(xDRI3ImportSyncobjReq);
|
REQUEST_SIZE_MATCH(xDRI3ImportSyncobjReq);
|
||||||
LEGAL_NEW_RESOURCE(stuff->syncobj, client);
|
LEGAL_NEW_RESOURCE(stuff->syncobj, client);
|
||||||
|
|
||||||
|
@ -620,7 +618,8 @@ proc_dri3_import_syncobj(ClientPtr client)
|
||||||
|
|
||||||
screen = drawable->pScreen;
|
screen = drawable->pScreen;
|
||||||
|
|
||||||
fd = ReadFdFromClient(client);
|
fd = client->recv_fd_list[0];
|
||||||
|
client->recv_fd_list[0] = -1;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,9 @@ typedef struct _saveSet {
|
||||||
#define SaveSetAssignToRoot(ss,tr) ((ss).toRoot = (tr))
|
#define SaveSetAssignToRoot(ss,tr) ((ss).toRoot = (tr))
|
||||||
#define SaveSetAssignMap(ss,m) ((ss).map = (m))
|
#define SaveSetAssignMap(ss,m) ((ss).map = (m))
|
||||||
|
|
||||||
|
/* currently largest one in use is 4 */
|
||||||
|
#define MAX_CLIENT_RECV_FD 8
|
||||||
|
|
||||||
typedef struct _Client {
|
typedef struct _Client {
|
||||||
void *requestBuffer;
|
void *requestBuffer;
|
||||||
void *osPrivate; /* for OS layer, including scheduler */
|
void *osPrivate; /* for OS layer, including scheduler */
|
||||||
|
@ -110,7 +113,9 @@ typedef struct _Client {
|
||||||
|
|
||||||
DeviceIntPtr clientPtr;
|
DeviceIntPtr clientPtr;
|
||||||
ClientIdPtr clientIds;
|
ClientIdPtr clientIds;
|
||||||
int req_fds;
|
|
||||||
|
int recv_fd_count;
|
||||||
|
int recv_fd_list[MAX_CLIENT_RECV_FD];
|
||||||
} ClientRec;
|
} ClientRec;
|
||||||
|
|
||||||
typedef struct _WorkQueue {
|
typedef struct _WorkQueue {
|
||||||
|
|
|
@ -86,8 +86,6 @@ typedef struct _NewClientRec *NewClientPtr;
|
||||||
|
|
||||||
extern _X_EXPORT int ReadRequestFromClient(ClientPtr /*client */ );
|
extern _X_EXPORT int ReadRequestFromClient(ClientPtr /*client */ );
|
||||||
|
|
||||||
extern _X_EXPORT int ReadFdFromClient(ClientPtr client);
|
|
||||||
|
|
||||||
extern _X_EXPORT int WriteFdToClient(ClientPtr client, int fd, Bool do_close);
|
extern _X_EXPORT int WriteFdToClient(ClientPtr client, int fd, Bool do_close);
|
||||||
|
|
||||||
extern _X_EXPORT Bool InsertFakeRequest(ClientPtr /*client */ ,
|
extern _X_EXPORT Bool InsertFakeRequest(ClientPtr /*client */ ,
|
||||||
|
|
36
os/io.c
36
os/io.c
|
@ -254,14 +254,6 @@ ReadRequestFromClient(ClientPtr client)
|
||||||
oc->input = oci;
|
oc->input = oci;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if XTRANS_SEND_FDS
|
|
||||||
/* Discard any unused file descriptors */
|
|
||||||
while (client->req_fds > 0) {
|
|
||||||
int req_fd = ReadFdFromClient(client);
|
|
||||||
if (req_fd >= 0)
|
|
||||||
close(req_fd);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* advance to start of next request */
|
/* advance to start of next request */
|
||||||
|
|
||||||
oci->bufptr += oci->lenLastReq;
|
oci->bufptr += oci->lenLastReq;
|
||||||
|
@ -461,25 +453,23 @@ ReadRequestFromClient(ClientPtr client)
|
||||||
client->index, req->reqType, req->data, req->length);
|
client->index, req->reqType, req->data, req->length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return needed;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ReadFdFromClient(ClientPtr client)
|
|
||||||
{
|
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
|
/* read the passed fds into Client struct */
|
||||||
|
client->recv_fd_count = 0;
|
||||||
#if XTRANS_SEND_FDS
|
#if XTRANS_SEND_FDS
|
||||||
if (client->req_fds > 0) {
|
for (;((client->recv_fd_count < MAX_CLIENT_RECV_FD) &&
|
||||||
OsCommPtr oc = (OsCommPtr) client->osPrivate;
|
(client->recv_fd_list[client->recv_fd_count] = _XSERVTransRecvFd(oc->trans_conn)) > 0);
|
||||||
|
client->recv_fd_count++) {}
|
||||||
--client->req_fds;
|
// just in case somebody sent a massive number of fd's
|
||||||
fd = _XSERVTransRecvFd(oc->trans_conn);
|
int _fd = -1;
|
||||||
} else
|
while ((_fd = _XSERVTransRecvFd(oc->trans_conn)) > 0)
|
||||||
LogMessage(X_ERROR, "Request asks for FD without setting req_fds\n");
|
close(_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return fd;
|
for (int x=client->recv_fd_count; x<MAX_CLIENT_RECV_FD; x++)
|
||||||
|
client->recv_fd_list[x] = -1;
|
||||||
|
|
||||||
|
return needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue