(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);
 | 
			
		||||
    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);
 | 
			
		||||
    fd = client->recv_fd_list[0];
 | 
			
		||||
    client->recv_fd_list[0] = -1;
 | 
			
		||||
 | 
			
		||||
    if (fd < 0)
 | 
			
		||||
        return BadMatch;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1462,7 +1463,6 @@ static int _X_COLD
 | 
			
		|||
SProcShmAttachFd(ClientPtr client)
 | 
			
		||||
{
 | 
			
		||||
    REQUEST(xShmAttachFdReq);
 | 
			
		||||
    SetReqFds(client, 1);
 | 
			
		||||
    REQUEST_SIZE_MATCH(xShmAttachFdReq);
 | 
			
		||||
    swapl(&stuff->shmseg);
 | 
			
		||||
    return ProcShmAttachFd(client);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -559,6 +559,14 @@ Dispatch(void)
 | 
			
		|||
                            (*client->requestVector[client->majorOp]) (client);
 | 
			
		||||
                        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)
 | 
			
		||||
                    SmartScheduleTime = GetTimeInMillis();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,13 +16,6 @@
 | 
			
		|||
#include "dixstruct.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
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -191,7 +191,6 @@ proc_dri3_pixmap_from_buffer(ClientPtr client)
 | 
			
		|||
    CARD32 stride, offset;
 | 
			
		||||
    int rc;
 | 
			
		||||
 | 
			
		||||
    SetReqFds(client, 1);
 | 
			
		||||
    REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
 | 
			
		||||
    LEGAL_NEW_RESOURCE(stuff->pixmap, client);
 | 
			
		||||
    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)
 | 
			
		||||
        return BadValue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +309,6 @@ proc_dri3_fence_from_fd(ClientPtr client)
 | 
			
		|||
    int fd;
 | 
			
		||||
    int status;
 | 
			
		||||
 | 
			
		||||
    SetReqFds(client, 1);
 | 
			
		||||
    REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
 | 
			
		||||
    LEGAL_NEW_RESOURCE(stuff->fence, client);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +316,8 @@ proc_dri3_fence_from_fd(ClientPtr client)
 | 
			
		|||
    if (status != Success)
 | 
			
		||||
        return status;
 | 
			
		||||
 | 
			
		||||
    fd = ReadFdFromClient(client);
 | 
			
		||||
    fd = client->recv_fd_list[0];
 | 
			
		||||
    client->recv_fd_list[0] = -1;
 | 
			
		||||
    if (fd < 0)
 | 
			
		||||
        return BadValue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -434,7 +434,6 @@ proc_dri3_pixmap_from_buffers(ClientPtr client)
 | 
			
		|||
    int rc;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    SetReqFds(client, stuff->num_buffers);
 | 
			
		||||
    REQUEST_SIZE_MATCH(xDRI3PixmapFromBuffersReq);
 | 
			
		||||
    LEGAL_NEW_RESOURCE(stuff->pixmap, client);
 | 
			
		||||
    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++) {
 | 
			
		||||
        fds[i] = ReadFdFromClient(client);
 | 
			
		||||
        fds[i] = client->recv_fd_list[i];
 | 
			
		||||
        if (fds[i] < 0) {
 | 
			
		||||
            while (--i >= 0)
 | 
			
		||||
                close(fds[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -609,7 +608,6 @@ proc_dri3_import_syncobj(ClientPtr client)
 | 
			
		|||
    int fd;
 | 
			
		||||
    int status;
 | 
			
		||||
 | 
			
		||||
    SetReqFds(client, 1);
 | 
			
		||||
    REQUEST_SIZE_MATCH(xDRI3ImportSyncobjReq);
 | 
			
		||||
    LEGAL_NEW_RESOURCE(stuff->syncobj, client);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -620,7 +618,8 @@ proc_dri3_import_syncobj(ClientPtr client)
 | 
			
		|||
 | 
			
		||||
    screen = drawable->pScreen;
 | 
			
		||||
 | 
			
		||||
    fd = ReadFdFromClient(client);
 | 
			
		||||
    fd = client->recv_fd_list[0];
 | 
			
		||||
    client->recv_fd_list[0] = -1;
 | 
			
		||||
    if (fd < 0)
 | 
			
		||||
        return BadValue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,9 @@ typedef struct _saveSet {
 | 
			
		|||
#define SaveSetAssignToRoot(ss,tr)  ((ss).toRoot = (tr))
 | 
			
		||||
#define SaveSetAssignMap(ss,m)      ((ss).map = (m))
 | 
			
		||||
 | 
			
		||||
/* currently largest one in use is 4 */
 | 
			
		||||
#define MAX_CLIENT_RECV_FD	8
 | 
			
		||||
 | 
			
		||||
typedef struct _Client {
 | 
			
		||||
    void *requestBuffer;
 | 
			
		||||
    void *osPrivate;             /* for OS layer, including scheduler */
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +113,9 @@ typedef struct _Client {
 | 
			
		|||
 | 
			
		||||
    DeviceIntPtr clientPtr;
 | 
			
		||||
    ClientIdPtr clientIds;
 | 
			
		||||
    int req_fds;
 | 
			
		||||
 | 
			
		||||
    int recv_fd_count;
 | 
			
		||||
    int recv_fd_list[MAX_CLIENT_RECV_FD];
 | 
			
		||||
} ClientRec;
 | 
			
		||||
 | 
			
		||||
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 ReadFdFromClient(ClientPtr client);
 | 
			
		||||
 | 
			
		||||
extern _X_EXPORT int WriteFdToClient(ClientPtr client, int fd, Bool do_close);
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#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 */
 | 
			
		||||
 | 
			
		||||
    oci->bufptr += oci->lenLastReq;
 | 
			
		||||
| 
						 | 
				
			
			@ -466,25 +458,23 @@ ReadRequestFromClient(ClientPtr client)
 | 
			
		|||
               client->index, req->reqType, req->data, req->length);
 | 
			
		||||
    }
 | 
			
		||||
#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 (client->req_fds > 0) {
 | 
			
		||||
        OsCommPtr oc = (OsCommPtr) client->osPrivate;
 | 
			
		||||
 | 
			
		||||
        --client->req_fds;
 | 
			
		||||
        fd = _XSERVTransRecvFd(oc->trans_conn);
 | 
			
		||||
    } else
 | 
			
		||||
        LogMessage(X_ERROR, "Request asks for FD without setting req_fds\n");
 | 
			
		||||
    for (;((client->recv_fd_count < MAX_CLIENT_RECV_FD) &&
 | 
			
		||||
           (client->recv_fd_list[client->recv_fd_count] = _XSERVTransRecvFd(oc->trans_conn)) > 0);
 | 
			
		||||
          client->recv_fd_count++) {}
 | 
			
		||||
    // just in case somebody sent a massive number of fd's
 | 
			
		||||
    int _fd = -1;
 | 
			
		||||
    while ((_fd = _XSERVTransRecvFd(oc->trans_conn)) > 0)
 | 
			
		||||
        close(_fd);
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue