summaryrefslogtreecommitdiffstats
path: root/libs/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2010-05-18 17:06:55 -0700
committerMathias Agopian <mathias@google.com>2010-05-20 18:00:42 -0700
commitbb641244d7d73312dc65b8e338df18b22e335107 (patch)
tree4a3e6e847513ad28bedd8de68da4ef2bd6ebf5ff /libs/surfaceflinger/SurfaceFlinger.cpp
parentdcf01e6644d0e9eca5aa08ee1b16a0d29d039e5e (diff)
downloadframeworks_native-bb641244d7d73312dc65b8e338df18b22e335107.zip
frameworks_native-bb641244d7d73312dc65b8e338df18b22e335107.tar.gz
frameworks_native-bb641244d7d73312dc65b8e338df18b22e335107.tar.bz2
fix the threading issue for setBuffercount()
this change introduces R/W locks in the right places. on the server-side, it guarantees that setBufferCount() is synchronized with "retire" and "resize". on the client-side, it guarantees that setBufferCount() is synchronized with "dequeue", "lockbuffer" and "queue"
Diffstat (limited to 'libs/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp34
1 files changed, 21 insertions, 13 deletions
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 62d829b..5a6893f 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -426,7 +426,7 @@ void SurfaceFlinger::waitForEvent()
timeout = waitTime>0 ? waitTime : 0;
}
- MessageList::value_type msg = mEventQueue.waitMessage(timeout);
+ sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
// see if we timed out
if (isFrozen()) {
@@ -461,9 +461,20 @@ void SurfaceFlinger::signal() const {
const_cast<SurfaceFlinger*>(this)->signalEvent();
}
-void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
+status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
+ nsecs_t reltime, uint32_t flags)
{
- mEventQueue.postMessage( new MessageBase(MessageQueue::INVALIDATE), delay);
+ return mEventQueue.postMessage(msg, reltime, flags);
+}
+
+status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
+ nsecs_t reltime, uint32_t flags)
+{
+ status_t res = mEventQueue.postMessage(msg, reltime, flags);
+ if (res == NO_ERROR) {
+ msg->wait();
+ }
+ return res;
}
// ----------------------------------------------------------------------------
@@ -1135,15 +1146,11 @@ uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
return android_atomic_and(~flags, &mTransactionFlags) & flags;
}
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
+uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
{
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
if ((old & flags)==0) { // wake the server up
- if (delay > 0) {
- signalDelayedEvent(delay);
- } else {
- signalEvent();
- }
+ signalEvent();
}
return old;
}
@@ -1245,7 +1252,7 @@ sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
//LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
int32_t id = client->generateId(pid);
- if (uint32_t(id) >= NUM_LAYERS_MAX) {
+ if (uint32_t(id) >= SharedBufferStack::NUM_LAYERS_MAX) {
LOGE("createSurface() failed, generateId = %d", id);
return surfaceHandle;
}
@@ -1399,7 +1406,7 @@ status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
}
};
- mEventQueue.postMessage( new MessageDestroySurface(this, layer) );
+ postMessageAsync( new MessageDestroySurface(this, layer) );
return NO_ERROR;
}
@@ -1672,7 +1679,7 @@ Client::~Client() {
int32_t Client::generateId(int pid)
{
const uint32_t i = clz( ~mBitmap );
- if (i >= NUM_LAYERS_MAX) {
+ if (i >= SharedBufferStack::NUM_LAYERS_MAX) {
return NO_MEMORY;
}
mPid = pid;
@@ -1699,7 +1706,8 @@ void Client::free(int32_t id)
}
bool Client::isValid(int32_t i) const {
- return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
+ return (uint32_t(i)<SharedBufferStack::NUM_LAYERS_MAX) &&
+ (mBitmap & (1<<(31-i)));
}
sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {