(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
							
								
									80f15897da
								
							
						
					
					
						commit
						1a557186dd
					
				| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -559,6 +559,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 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,8 +90,6 @@ extern _X_EXPORT Bool WaitForSomething(Bool clients_are_ready);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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;
 | 
				
			||||||
| 
						 | 
					@ -466,25 +458,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