summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdrm/xf86drm.c61
-rw-r--r--libdrm/xf86drm.h3
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