summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--freedreno/freedreno_device.c12
-rw-r--r--freedreno/freedreno_drmif.h1
-rw-r--r--freedreno/freedreno_priv.h2
3 files changed, 15 insertions, 0 deletions
diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c
index 6486983d..23e086bb 100644
--- a/freedreno/freedreno_device.c
+++ b/freedreno/freedreno_device.c
@@ -135,6 +135,16 @@ struct fd_device * fd_device_new(int fd)
return dev;
}
+/* like fd_device_new() but creates it's own private dup() of the fd
+ * which is close()d when the device is finalized.
+ */
+struct fd_device * fd_device_new_dup(int fd)
+{
+ struct fd_device *dev = fd_device_new(dup(fd));
+ dev->closefd = 1;
+ return dev;
+}
+
struct fd_device * fd_device_ref(struct fd_device *dev)
{
atomic_inc(&dev->refcnt);
@@ -147,6 +157,8 @@ static void fd_device_del_impl(struct fd_device *dev)
drmHashDestroy(dev->handle_table);
drmHashDestroy(dev->name_table);
drmHashDelete(dev_table, dev->fd);
+ if (dev->closefd)
+ close(dev->fd);
dev->funcs->destroy(dev);
}
diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h
index 6a40ab8f..f3a01aff 100644
--- a/freedreno/freedreno_drmif.h
+++ b/freedreno/freedreno_drmif.h
@@ -72,6 +72,7 @@ enum fd_param_id {
*/
struct fd_device * fd_device_new(int fd);
+struct fd_device * fd_device_new_dup(int fd);
struct fd_device * fd_device_ref(struct fd_device *dev);
void fd_device_del(struct fd_device *dev);
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index 061d807e..d5cf9f97 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -84,6 +84,8 @@ struct fd_device {
struct fd_bo_bucket cache_bucket[14 * 4];
int num_buckets;
time_t time;
+
+ int closefd; /* call close(fd) upon destruction */
};
void fd_cleanup_bo_cache(struct fd_device *dev, time_t time);