Files
OpenMQTT-Gateway/lib/ESPiLight/pilight/libs/openzwave/platform/Wait.cpp
T
Florian 67dd7ac078 update esppilight lib
content of the library is not filtered on 433mhz only
2018-11-28 20:41:37 +01:00

183 lines
4.7 KiB
C++

//-----------------------------------------------------------------------------
//
// Wait.cpp
//
// Base class for objects we want to be able to wait for.
//
// Copyright (c) 2010 Mal Lansell <mal@lansell.org>
// All rights reserved.
//
// SOFTWARE NOTICE AND LICENSE
//
// This file is part of OpenZWave.
//
// OpenZWave is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// OpenZWave is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenZWave. If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
#include <stdio.h>
#include "../Defs.h"
#include "Wait.h"
#include "Event.h"
#include "Log.h"
#ifdef _WIN32
#include "windows/WaitImpl.h" // Platform-specific implementation of a Wait object
#else
#include "unix/WaitImpl.h" // Platform-specific implementation of a Wait object
#endif
using namespace OpenZWave;
void WaitMultipleCallback( void* _context );
//-----------------------------------------------------------------------------
// <Wait::Wait>
// Constructor
//-----------------------------------------------------------------------------
Wait::Wait
(
)
{
m_pImpl = new WaitImpl( this );
}
//-----------------------------------------------------------------------------
// <Wait::~Wait>
// Destructor
//-----------------------------------------------------------------------------
Wait::~Wait
(
)
{
delete m_pImpl;
}
//-----------------------------------------------------------------------------
// <Wait::AddWatcher>
// Add a watcher to our object.
//-----------------------------------------------------------------------------
void Wait::AddWatcher
(
pfnWaitNotification_t _callback,
void* _context
)
{
if( !_callback )
{
assert(0);
return;
}
// Add a ref so our object cannot disappear while being watched
AddRef();
// Add the watcher (platform specific code required here for thread safety)
m_pImpl->AddWatcher( _callback, _context );
}
//-----------------------------------------------------------------------------
// <Wait::RemoveWatcher>
// Remove a watcher from our object.
//-----------------------------------------------------------------------------
void Wait::RemoveWatcher
(
pfnWaitNotification_t _callback,
void* _context
)
{
if( m_pImpl->RemoveWatcher( _callback, _context ) )
{
Release();
}
}
//-----------------------------------------------------------------------------
// <Wait::Notify>
// Notify all the watchers that the object has become signalled
//-----------------------------------------------------------------------------
void Wait::Notify
(
)
{
m_pImpl->Notify();
}
//-----------------------------------------------------------------------------
// <Wait::Multiple>
// Wait for one of multiple objects to become signalled.
//-----------------------------------------------------------------------------
int32 Wait::Multiple
(
Wait** _objects,
uint32 _numObjects,
int32 _timeout // = -1
)
{
uint32 i;
// Create an event that will be set when any of the objects in the list becomes signalled.
Event* waitEvent = new Event();
// Add a watcher to each object in the list, passing in the event as the context.
for( i=0; i<_numObjects; ++i )
{
_objects[i]->AddWatcher( WaitMultipleCallback, waitEvent );
}
int32 res = -1; // Default to timeout result
string str = "";
if( waitEvent->Wait( _timeout ) )
{
// An object was signalled. Run through the list
// and see which one it was.
for( i=0; i<_numObjects; ++i )
{
if( _objects[i]->IsSignalled() )
{
if( res == -1 )
res = (int32)i;
char buf[15];
snprintf(buf, sizeof(buf), "%d, ", i);
str += buf;
}
}
}
//Log::Write( LogLevel_Debug, "Wait::Multiple res=%d num=%d >%s", res, _numObjects, str.c_str() );
// Remove the watchers
for( i=0; i<_numObjects; ++i )
{
_objects[i]->RemoveWatcher( WaitMultipleCallback, waitEvent );
}
// We're done with the event now
waitEvent->Release();
return res;
}
//-----------------------------------------------------------------------------
// <WaitMultipleCallback>
// Callback handler for the watchers added during WaitImpl::Multiple
//-----------------------------------------------------------------------------
void WaitMultipleCallback
(
void* _context
)
{
Event* waitEvent = (Event*)_context;
waitEvent->Set();
}