/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "SurfaceFlingerSynchro" #include #include #include #include #include #include #include #include #include #include #include namespace android { // --------------------------------------------------------------------------- SurfaceFlingerSynchro::Barrier::Barrier() : state(CLOSED) { } SurfaceFlingerSynchro::Barrier::~Barrier() { } void SurfaceFlingerSynchro::Barrier::open() { asm volatile ("":::"memory"); Mutex::Autolock _l(lock); state = OPENED; cv.broadcast(); } void SurfaceFlingerSynchro::Barrier::close() { Mutex::Autolock _l(lock); state = CLOSED; } void SurfaceFlingerSynchro::Barrier::waitAndClose() { Mutex::Autolock _l(lock); while (state == CLOSED) { // we're about to wait, flush the binder command buffer IPCThreadState::self()->flushCommands(); cv.wait(lock); } state = CLOSED; } status_t SurfaceFlingerSynchro::Barrier::waitAndClose(nsecs_t timeout) { Mutex::Autolock _l(lock); while (state == CLOSED) { // we're about to wait, flush the binder command buffer IPCThreadState::self()->flushCommands(); int err = cv.waitRelative(lock, timeout); if (err != 0) return err; } state = CLOSED; return NO_ERROR; } // --------------------------------------------------------------------------- SurfaceFlingerSynchro::SurfaceFlingerSynchro(const sp& flinger) : mSurfaceComposer(flinger) { } SurfaceFlingerSynchro::SurfaceFlingerSynchro() { } SurfaceFlingerSynchro::~SurfaceFlingerSynchro() { } status_t SurfaceFlingerSynchro::signal() { mSurfaceComposer->signal(); return NO_ERROR; } status_t SurfaceFlingerSynchro::wait() { mBarrier.waitAndClose(); return NO_ERROR; } status_t SurfaceFlingerSynchro::wait(nsecs_t timeout) { if (timeout == 0) return SurfaceFlingerSynchro::wait(); return mBarrier.waitAndClose(timeout); } void SurfaceFlingerSynchro::open() { mBarrier.open(); } // --------------------------------------------------------------------------- }; // namespace android