summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-10 20:39:40 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-10 20:39:40 +0000
commitce23be8fcffa2e63f13ae00d45a545a3d5f5e157 (patch)
tree0a6e28d4f7c180b344128d6901c3c09795c70a47
parent87182226a17a5f5cd69f8b783a38d704f3b9bf63 (diff)
downloadchromium_src-ce23be8fcffa2e63f13ae00d45a545a3d5f5e157.zip
chromium_src-ce23be8fcffa2e63f13ae00d45a545a3d5f5e157.tar.gz
chromium_src-ce23be8fcffa2e63f13ae00d45a545a3d5f5e157.tar.bz2
linux: fix race in TransportDIB passing
There was a race condition when the renderer passes a TransportDIB to the plugin process. It is possible that the renderer destroys the TransportDIB before the plugin handles the message, in which case the plugin will fail to map the shm handle. This also cleans up a couple of things. BUG=18320 Review URL: http://codereview.chromium.org/164226 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22949 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/common/transport_dib.h2
-rw-r--r--chrome/common/transport_dib_linux.cc4
-rw-r--r--chrome/plugin/webplugin_proxy.cc8
3 files changed, 11 insertions, 3 deletions
diff --git a/chrome/common/transport_dib.h b/chrome/common/transport_dib.h
index 6d137ff..c28d78d 100644
--- a/chrome/common/transport_dib.h
+++ b/chrome/common/transport_dib.h
@@ -142,6 +142,8 @@ class TransportDIB {
Display* display_; // connection to the X server
#endif
size_t size_; // length, in bytes
+
+ DISALLOW_COPY_AND_ASSIGN(TransportDIB);
};
class MessageLoop;
diff --git a/chrome/common/transport_dib_linux.cc b/chrome/common/transport_dib_linux.cc
index d239da2..d3ffe69 100644
--- a/chrome/common/transport_dib_linux.cc
+++ b/chrome/common/transport_dib_linux.cc
@@ -45,7 +45,7 @@ TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) {
if (shmkey == -1) {
DLOG(ERROR) << "Failed to create SysV shared memory region"
<< " errno:" << errno;
- return false;
+ return NULL;
}
void* address = shmat(shmkey, NULL /* desired address */, 0 /* flags */);
@@ -54,7 +54,7 @@ TransportDIB* TransportDIB::Create(size_t size, uint32 sequence_num) {
// that the kernel will automatically clean it up for us.
shmctl(shmkey, IPC_RMID, 0);
if (address == kInvalidAddress)
- return false;
+ return NULL;
TransportDIB* dib = new TransportDIB;
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 0e2e006..8a04650 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -636,7 +636,13 @@ void WebPluginProxy::SetWindowlessBuffer(
int width = delegate_->GetRect().width();
int height = delegate_->GetRect().height();
windowless_dib_.reset(TransportDIB::Map(windowless_buffer));
- windowless_canvas_.reset(windowless_dib_->GetPlatformCanvas(width, height));
+ if (windowless_dib_.get()) {
+ windowless_canvas_.reset(windowless_dib_->GetPlatformCanvas(width, height));
+ } else {
+ // This can happen if the renderer has already destroyed the TransportDIB
+ // by the time we receive the handle, e.g. in case of multiple resizes.
+ windowless_canvas_.reset();
+ }
background_dib_.reset(TransportDIB::Map(background_buffer));
if (background_dib_.get()) {
background_canvas_.reset(background_dib_->GetPlatformCanvas(width, height));