gralloc: refcount private_module_t
authorGreg Hackmann <ghackmann@google.com>
Wed, 2 Apr 2014 18:52:10 +0000 (11:52 -0700)
committerGreg Hackmann <ghackmann@google.com>
Thu, 3 Apr 2014 16:43:48 +0000 (09:43 -0700)
gralloc_open() can be called multiple times in the same process, which
led to the existing ion fd leaking on each open; the surviving fd also
leaked on close.  Refcount the private_module_t to prevent this.

Bug: 13633155
Change-Id: I09ac8096fe0101b91b23e7c8d2ee9e11efe29b03
Signed-off-by: Greg Hackmann <ghackmann@google.com>
gralloc/gralloc.cpp
include/gralloc_priv.h

index 69dc61df73e1bec40bc8f25a880ce7bacf7bdd17..3c56a1e7556432a0a8474162d08af3f5f0fca915 100644 (file)
@@ -107,6 +107,7 @@ flags: 0,
 numBuffers: 0,
 bufferMask: 0,
 lock: PTHREAD_MUTEX_INITIALIZER,
+refcount: 0,
 currentBuffer: 0,
 ionfd: -1,
 };
@@ -400,6 +401,14 @@ static int gralloc_close(struct hw_device_t *dev)
 {
     gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
     if (ctx) {
+        private_module_t *p = reinterpret_cast<private_module_t*>(ctx->device.common.module);
+        pthread_mutex_lock(&p->lock);
+        LOG_ALWAYS_FATAL_IF(!p->refcount);
+        p->refcount--;
+        if (!p->refcount)
+            close(p->ionfd);
+        pthread_mutex_unlock(&p->lock);
+
         /* TODO: keep a list of all buffer_handle_t created, and free them
          * all here.
          */
@@ -429,7 +438,11 @@ int gralloc_device_open(const hw_module_t* module, const char* name,
         dev->device.free = gralloc_free;
 
         private_module_t *p = reinterpret_cast<private_module_t*>(dev->device.common.module);
-        p->ionfd = ion_open();
+        pthread_mutex_lock(&p->lock);
+        if (!p->refcount)
+            p->ionfd = ion_open();
+        p->refcount++;
+        pthread_mutex_unlock(&p->lock);
 
         *device = &dev->device.common;
         status = 0;
index bce84e425e017c400715872fdefa9e3f9ca1b416..416101c934571062f927d18b4e267a9a293b2421 100644 (file)
@@ -43,6 +43,7 @@ struct private_module_t {
     uint32_t numBuffers;
     uint32_t bufferMask;
     pthread_mutex_t lock;
+    unsigned int refcount;
     buffer_handle_t currentBuffer;
     int ionfd;