diff options
-rw-r--r-- | libdrm/xf86drm.c | 61 | ||||
-rw-r--r-- | libdrm/xf86drm.h | 3 |
2 files changed, 64 insertions, 0 deletions
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 05b40f7a..56450e80 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -3215,3 +3215,64 @@ int drmMMUnlock(int fd, unsigned memType) return ret; } + +#define DRM_MAX_FDS 16 +static struct { + char *BusID; + int fd; + int refcount; +} connection[DRM_MAX_FDS]; + +static int nr_fds = 0; + +int drmOpenOnce(void *unused, + const char *BusID, + int *newlyopened) +{ + int i; + int fd; + + for (i = 0; i < nr_fds; i++) + if (strcmp(BusID, connection[i].BusID) == 0) { + connection[i].refcount++; + *newlyopened = 0; + return connection[i].fd; + } + + fd = drmOpen(unused, BusID); + if (fd <= 0 || nr_fds == DRM_MAX_FDS) + return fd; + + connection[nr_fds].BusID = strdup(BusID); + connection[nr_fds].fd = fd; + connection[nr_fds].refcount = 1; + *newlyopened = 1; + + if (0) + fprintf(stderr, "saved connection %d for %s %d\n", + nr_fds, connection[nr_fds].BusID, + strcmp(BusID, connection[nr_fds].BusID)); + + nr_fds++; + + return fd; +} + +void drmCloseOnce(int fd) +{ + int i; + + for (i = 0; i < nr_fds; i++) { + if (fd == connection[i].fd) { + if (--connection[i].refcount == 0) { + drmClose(connection[i].fd); + free(connection[i].BusID); + + if (i < --nr_fds) + connection[i] = connection[nr_fds]; + + return; + } + } + } +} diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index 4d9580c4..34c9ec0e 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -655,6 +655,9 @@ extern int drmSLLookupNeighbors(void *l, unsigned long key, unsigned long *prev_key, void **prev_value, unsigned long *next_key, void **next_value); +extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened); +extern void drmCloseOnce(int fd); + #include "xf86mm.h" #endif |