+ dev->handle_table = drmHashCreate();
+ dev->name_table = drmHashCreate();
+ return dev;
+}
+
+/* use inode for key into dev_table, rather than fd, to avoid getting
+ * confused by multiple-opens:
+ */
+static int devkey(int fd)
+{
+ struct stat s;
+ if (fstat(fd, &s)) {
+ ERROR_MSG("stat failed: %s", strerror(errno));
+ return -1;
+ }
+ return s.st_ino;
+}
+
+struct fd_device * fd_device_new(int fd)
+{
+ struct fd_device *dev = NULL;
+ int key = devkey(fd);
+
+ pthread_mutex_lock(&table_lock);
+
+ if (!dev_table)
+ dev_table = drmHashCreate();
+
+ if (drmHashLookup(dev_table, key, (void **)&dev)) {
+ dev = fd_device_new_impl(fd);
+ drmHashInsert(dev_table, key, dev);
+ } else {
+ dev = fd_device_ref(dev);
+ }
+
+ pthread_mutex_unlock(&table_lock);
+
+ return dev;
+}
+
+struct fd_device * fd_device_ref(struct fd_device *dev)
+{
+ atomic_inc(&dev->refcnt);