utc-Dali-MeshData.cpp
utc-Dali-Model.cpp
utc-Dali-MouseWheelEvent.cpp
+ utc-Dali-Mutex.cpp
utc-Dali-NinePatchImages.cpp
utc-Dali-ObjectRegistry.cpp
utc-Dali-PanGesture.cpp
ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.cpp ${TC_SOURCES})
TARGET_LINK_LIBRARIES(${EXEC_NAME}
${${CAPI_LIB}_LIBRARIES}
+ -lpthread
)
INSTALL(PROGRAMS ${EXEC_NAME}
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dali/public-api/dali-core.h>
+#include <dali-test-suite-utils.h>
+
+using Dali::Mutex;
+
+int UtcDaliMutexSingleThread(void)
+{
+ tet_infoline("Testing Dali::Mutex in a single thread");
+
+ {
+ Mutex mutex1;
+ DALI_TEST_EQUALS( false, mutex1.IsLocked(), TEST_LOCATION );
+ }
+
+ {
+ Mutex mutex2;
+ Mutex::ScopedLock lock( mutex2 );
+ DALI_TEST_EQUALS( true, mutex2.IsLocked(), TEST_LOCATION );
+ }
+
+ Mutex mutex3;
+ {
+ Mutex::ScopedLock lock( mutex3 );
+ }
+ DALI_TEST_EQUALS( false, mutex3.IsLocked(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+namespace // for local variables to avoid name clashes
+{
+int gGlobalValue = 0;
+Mutex* gGlobalValueMutex;
+bool gWorkerThreadWait = true;
+enum ThreadState { INIT, RUN, LOCKING, TERMINATE } gWorkerThreadState = INIT;
+}
+void* WorkerThread1( void* ptr )
+{
+ gWorkerThreadState = RUN;
+ {
+ Mutex::ScopedLock lock( *gGlobalValueMutex );
+ gWorkerThreadState = LOCKING;
+ gGlobalValue = -1;
+ while( gWorkerThreadWait ) // wait till we can exit
+ {
+ usleep( 1 ); // 1 microsecond
+ }
+ }
+ gWorkerThreadState = TERMINATE;
+ return NULL;
+}
+
+int UtcDaliMutexMultiThread(void)
+{
+ tet_infoline("Testing Dali::Mutex multithreaded");
+
+ gGlobalValueMutex = new Dali::Mutex;
+
+ pthread_t thread1;
+ // initialize values
+ gGlobalValue = 0;
+ gWorkerThreadWait = true;
+ DALI_TEST_EQUALS( INIT, gWorkerThreadState, TEST_LOCATION );
+ DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
+ DALI_TEST_EQUALS( false, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
+
+ // lock the mutex
+ {
+ Mutex::ScopedLock lock( *gGlobalValueMutex );
+ DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
+ pthread_create(&thread1, NULL, &WorkerThread1, NULL );
+ // wait till the thread is in run state
+ while( RUN != gWorkerThreadState )
+ {
+ usleep( 1 ); // 1 microsecond
+ }
+ // now the thread is running and mutex is still locked by this thread so value is not changed
+ DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 0, gGlobalValue, TEST_LOCATION );
+ // drop out of scope, releases our lock
+ }
+ // now child thread is allowed to change the value
+ // wait till the thread is in locking state
+ while( LOCKING != gWorkerThreadState )
+ {
+ usleep( 1 ); // 1 microsecond
+ }
+ // mutex is locked, but not by us, by the child thread
+ DALI_TEST_EQUALS( true, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
+ // value is changed
+ DALI_TEST_EQUALS( -1, gGlobalValue, TEST_LOCATION );
+ // let worker finish
+ gWorkerThreadWait = false;
+ // wait till the thread is terminated state
+ while( TERMINATE != gWorkerThreadState )
+ {
+ usleep( 1 ); // 1 microsecond
+ }
+ DALI_TEST_EQUALS( false, gGlobalValueMutex->IsLocked(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliMutexNonCopyable(void)
+{
+ // we want to make sure that mutex is not copyable (its copy constructor is not defined)
+ // this test will stop compiling if Mutex has compiler generated copy constructor
+ DALI_COMPILE_TIME_ASSERT( !__has_trivial_copy( Mutex ) );
+
+ DALI_TEST_CHECK( true );
+ END_TEST;
+}
+
+
$(DALI_CFLAGS)
libdali_core_la_LIBADD = $(DALI_LDFLAGS) \
- -lboost_thread \
- -lboost_system
+ -lpthread
# Create an empty shaderbin dir
install-data-local:
// CLASS HEADER
#include <dali/internal/event/common/notification-manager.h>
-// EXTERNAL INCLUDES
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wall"
-
-#include <boost/thread/mutex.hpp>
-
-#pragma clang diagnostic pop
-#else
-
-#include <boost/thread/mutex.hpp>
-
-#endif // __clang__
-
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/mutex.h>
#include <dali/internal/common/owner-container.h>
#include <dali/internal/common/message.h>
#include <dali/internal/event/common/property-notification-impl.h>
}
}
-typedef boost::mutex MessageQueueMutex;
+typedef Dali::Mutex MessageQueueMutex;
typedef OwnerContainer< MessageBase* > MessageContainer;
struct NotificationManager::Impl
void NotificationManager::QueueCompleteNotification( CompleteNotificationInterface* instance )
{
// queueMutex must be locked whilst accessing queues
- MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+ MessageQueueMutex::ScopedLock lock( mImpl->queueMutex );
mImpl->updateWorkingInterfaceQueue.PushBack( instance );
}
DALI_ASSERT_DEBUG( NULL != message );
// queueMutex must be locked whilst accessing queues
- MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+ MessageQueueMutex::ScopedLock lock( mImpl->queueMutex );
mImpl->updateWorkingMessageQueue.PushBack( message );
}
void NotificationManager::UpdateCompleted()
{
// queueMutex must be locked whilst accessing queues
- MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+ MessageQueueMutex::ScopedLock lock( mImpl->queueMutex );
// Move messages from update working queue to completed queue
// note that in theory its possible for update completed to have last frames
// events as well still hanging around. we need to keep them as well
bool NotificationManager::MessagesToProcess()
{
// queueMutex must be locked whilst accessing queues
- MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+ MessageQueueMutex::ScopedLock lock( mImpl->queueMutex );
return ( 0u < mImpl->updateCompletedMessageQueue.Count() ||
( 0u < mImpl->updateCompletedInterfaceQueue.Count() ) );
{
// queueMutex must be locked whilst accessing queues
{
- MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+ MessageQueueMutex::ScopedLock lock( mImpl->queueMutex );
// Move messages from update completed queue to event queue
// note that in theory its possible for event queue to have
// CLASS HEADER
#include <dali/internal/update/queue/update-message-queue.h>
-// EXTERNAL INCLUDES
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wall"
-#include <boost/thread/mutex.hpp>
-#pragma clang diagnostic pop
-#else
-#include <boost/thread/mutex.hpp>
-#endif // ifdef __clang
-
// INTERNAL INCLUDES
#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/common/mutex.h>
#include <dali/integration-api/render-controller.h>
#include <dali/internal/common/message-buffer.h>
#include <dali/internal/render/common/performance-monitor.h>
typedef vector< MessageBuffer* > MessageBufferQueue;
typedef MessageBufferQueue::iterator MessageBufferIter;
-typedef boost::mutex MessageQueueMutex;
+typedef Dali::Mutex MessageQueueMutex;
} // unnamed namespace
if ( messagesToProcess )
{
// queueMutex must be locked whilst accessing processQueue or recycleQueue
- MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+ MessageQueueMutex::ScopedLock lock( mImpl->queueMutex );
mImpl->processQueue.push_back( mImpl->currentMessageBuffer );
mImpl->currentMessageBuffer = NULL;
PERF_MONITOR_START(PerformanceMonitor::PROCESS_MESSAGES);
// queueMutex must be locked whilst accessing queue
- MessageQueueMutex::scoped_lock lock( mImpl->queueMutex );
+ MessageQueueMutex::ScopedLock lock( mImpl->queueMutex );
const MessageBufferIter processQueueEndIter = mImpl->processQueue.end();
for ( MessageBufferIter iter = mImpl->processQueue.begin(); iter != processQueueEndIter ; ++iter )
--- /dev/null
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/public-api/common/mutex.h>
+
+// EXTERNAL INCLUDES
+#include <pthread.h>
+
+namespace Dali
+{
+
+struct Mutex::MutexImpl
+{
+ pthread_mutex_t mutex;
+ bool locked;
+};
+
+Mutex::Mutex()
+: mImpl( new MutexImpl )
+{
+ pthread_mutex_init( &mImpl->mutex, NULL );
+ mImpl->locked = false;
+}
+
+Mutex::~Mutex()
+{
+ pthread_mutex_destroy( &mImpl->mutex );
+ // nothing else to do as there is no Lock/Unlock API
+ // ScopedLock destructor will always unlock the mutex
+ delete mImpl;
+}
+
+bool Mutex::IsLocked()
+{
+ return mImpl->locked;
+}
+
+Mutex::ScopedLock::ScopedLock( Mutex& mutex )
+: mMutex( mutex )
+{
+ pthread_mutex_lock( &mMutex.mImpl->mutex );
+ mMutex.mImpl->locked = true;
+}
+
+Mutex::ScopedLock::~ScopedLock()
+{
+ pthread_mutex_unlock( &mMutex.mImpl->mutex );
+ mMutex.mImpl->locked = false;
+}
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_MUTEX_H__
+#define __DALI_MUTEX_H__
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+
+/**
+ * The top level DALi namespace
+ */
+namespace Dali
+{
+
+/**
+ * Class to synchronize access to critical resources from multiple threads
+ */
+class DALI_IMPORT_API Mutex
+{
+public:
+
+ /**
+ * @brief Constructor, acquires the mutex from the underlying OS
+ */
+ Mutex();
+
+ /**
+ * @brief Destructor, non virtual as this is not meant as a base class
+ */
+ ~Mutex();
+
+ /**
+ * @brief Check if the mutex is locked
+ * @return true if the mutex is locked
+ */
+ bool IsLocked();
+
+public:
+
+ /**
+ * Helper class to do a scoped lock on a mutex implementing the RAII idiom.
+ * Note! this class *does not* prevent a deadlock in the case when same thread is
+ * locking the same mutex twice.
+ */
+ class ScopedLock
+ {
+ public:
+
+ /**
+ * Constructor
+ * @param mutex to lock
+ */
+ ScopedLock( Mutex& mutex );
+
+ /**
+ * Destructor, releases the lock
+ */
+ ~ScopedLock();
+
+ private:
+ Mutex& mMutex;
+ };
+
+private:
+
+ /// Not implemented as Mutex is not copyable
+ Mutex( const Mutex& );
+ const Mutex& operator= ( const Mutex& );
+
+ struct MutexImpl;
+ MutexImpl* mImpl;
+
+};
+
+} // namespace Dali
+
+#endif // __DALI_MUTEX_H__
#include <dali/public-api/common/intrusive-ptr.h>
#include <dali/public-api/common/light.h>
#include <dali/public-api/common/loading-state.h>
+#include <dali/public-api/common/mutex.h>
#include <dali/public-api/common/stage.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/common/view-mode.h>
$(public_api_src_dir)/common/dali-common.cpp \
$(public_api_src_dir)/common/dali-vector.cpp \
$(public_api_src_dir)/common/light.cpp \
+ $(public_api_src_dir)/common/mutex.cpp \
$(public_api_src_dir)/common/stage.cpp \
$(public_api_src_dir)/dynamics/dynamics-body.cpp \
$(public_api_src_dir)/dynamics/dynamics-body-config.cpp \
$(public_api_src_dir)/common/intrusive-ptr.h \
$(public_api_src_dir)/common/light.h \
$(public_api_src_dir)/common/loading-state.h \
+ $(public_api_src_dir)/common/mutex.h \
$(public_api_src_dir)/common/map-wrapper.h \
$(public_api_src_dir)/common/ref-counted-dali-vector.h \
$(public_api_src_dir)/common/set-wrapper.h \