2014-07-03 17:24:17 +00:00
# include <zkutil/Lock.h>
using namespace zkutil ;
bool Lock : : tryLock ( )
{
if ( locked )
{
/// проверим, что нода создана и я е е владелец
check ( ) ;
}
else
{
size_t attempt ;
std : : string dummy ;
2014-08-13 13:41:08 +00:00
int32_t code = zookeeper - > tryCreateWithRetries ( lock_path , lock_message , zkutil : : CreateMode : : Ephemeral , dummy , & attempt ) ;
2014-07-03 17:24:17 +00:00
if ( code = = ZNODEEXISTS )
{
if ( attempt = = 0 )
locked = false ;
else
{
zkutil : : Stat stat ;
zookeeper - > get ( lock_path , & stat ) ;
if ( stat . ephemeralOwner = = zookeeper - > getClientID ( ) )
locked = true ;
else
locked = false ;
}
}
else if ( code = = ZOK )
{
locked = true ;
}
else
{
throw zkutil : : KeeperException ( code ) ;
}
}
return locked ;
}
void Lock : : unlock ( )
{
if ( locked )
{
/// проверим, что до сих пор мы владельцы ноды
check ( ) ;
size_t attempt ;
int32_t code = zookeeper - > tryRemoveWithRetries ( lock_path , - 1 , & attempt ) ;
if ( attempt )
{
if ( code ! = ZOK )
throw zkutil : : KeeperException ( code ) ;
}
else
{
if ( code = = ZNONODE )
LOG_ERROR ( log , " Node " < < lock_path < < " has been already removed. Probably due to network error. " ) ;
else if ( code ! = ZOK )
throw zkutil : : KeeperException ( code ) ;
}
locked = false ;
}
}
Lock : : Status Lock : : check ( )
{
Status status = checkImpl ( ) ;
if ( ( locked & & status ! = LOCKED_BY_ME ) | | ( ! locked & & ( status ! = UNLOCKED & & status ! = LOCKED_BY_OTHER ) ) )
2014-07-30 12:31:19 +00:00
throw zkutil : : KeeperException ( std : : string ( " Incompability of local state and state in zookeeper. Local is " ) + ( locked ? " locked " : " unlocked " ) + " . Zookeeper state is " + status2String ( status ) ) ;
return status ;
2014-07-03 17:24:17 +00:00
}
Lock : : Status Lock : : checkImpl ( )
{
Stat stat ;
2014-07-30 12:31:19 +00:00
std : : string dummy ;
2014-08-15 10:20:34 +00:00
bool result = zookeeper - > tryGet ( lock_path , dummy , & stat ) ;
if ( ! result )
2014-07-03 17:24:17 +00:00
return UNLOCKED ;
2014-08-15 10:20:34 +00:00
else
2014-07-03 17:24:17 +00:00
{
if ( stat . ephemeralOwner = = zookeeper - > getClientID ( ) )
{
return LOCKED_BY_ME ;
}
else
{
return LOCKED_BY_OTHER ;
}
}
}
std : : string Lock : : status2String ( Status status )
{
if ( status > = END )
throw zkutil : : KeeperException ( " Wrong status code: " + std : : to_string ( status ) ) ;
static const char * names [ ] = { " Unlocked " , " Locked by me " , " Locked by other " } ;
return names [ status ] ;
}