c_bool determineFirstLeaseToExpire( c_object o, c_voidp arg) { c_time headExpTime; c_time leaseExpTime; v_leaseAction leaseAction = v_leaseAction(o); v_leaseManager lm = v_leaseManager(arg); if (lm->firstLeaseToExpire == NULL) { lm->firstLeaseToExpire = c_keep(leaseAction); } else { headExpTime = v_leaseExpiryTime(lm->firstLeaseToExpire->lease); leaseExpTime = v_leaseExpiryTime(leaseAction->lease); if (c_timeCompare(headExpTime, leaseExpTime) == C_GT) { c_free(lm->firstLeaseToExpire); lm->firstLeaseToExpire = c_keep(leaseAction); } } return TRUE; }
void v_leaseDeinit( v_lease lease) { v_leaseManager lm; assert(lease != NULL); assert(C_TYPECHECK(lease,v_lease)); if (lease != NULL) { lm = v_leaseManager(c_take(lease->observers)); while (lm != NULL) { c_free(lm); lm = v_leaseManager(c_take(lease->observers)); } c_free(lease->observers); lease->observers = NULL; } }
void v_leaseRenew( v_lease lease, v_duration leaseDuration) { c_iter observers = NULL; v_leaseManager observer; if (lease != NULL) { assert(C_TYPECHECK(lease, v_lease)); v_leaseLock(lease); lease->expiryTime = c_timeAdd(v_timeGet(), leaseDuration); lease->duration = leaseDuration; /* Collect all observers, so they can be notified of the lease change * Must do a seperate collect as the lease mutex is 'lower' then the * leaseManager mutex. So to prevent deadlock we can not directly notify * the lease manager as we walk the collection */ if(lease->observers) { c_walk(lease->observers, v_leaseCollectObservers, &observers); } v_leaseUnlock(lease); if(observers) { observer = v_leaseManager(c_iterTakeFirst(observers)); while (observer != NULL) { v_leaseManagerNotify( observer, lease, V_EVENT_LEASE_RENEWED); c_free(observer); observer = v_leaseManager(c_iterTakeFirst(observers)); } c_iterFree(observers); } } }
/************************************************************** * constructor/destructor **************************************************************/ v_leaseManager v_leaseManagerNew( v_kernel k) { v_leaseManager _this; assert(C_TYPECHECK(k, v_kernel)); _this = v_leaseManager(v_objectNew(k, K_LEASEMANAGER)); if(_this) { v_leaseManagerInit(_this); } else { OS_REPORT(OS_ERROR, "v_leaseManager", 0, "Failed to create a v_leaseManager object. " "Most likely not enough shared memory available " "to complete the operation."); } return _this; }
void v_leaseRenew( v_lease lease, v_duration* leaseDuration /* may be NULL */) { c_iter observers = NULL; v_leaseManager observer; c_time newExpiryTime; c_equality cmp; if (lease != NULL) { assert(C_TYPECHECK(lease, v_lease)); v_leaseLock(lease); /* Is a new lease duration provided, if so replace the current lease * duration with the new one */ if(leaseDuration != NULL) { lease->duration = *leaseDuration; } /* else do nothing */ /* Calculate the new expiry time */ newExpiryTime = c_timeAdd(v_timeGet(), lease->duration); /* Is the new expiryTime earlier then the current expiryTime? */ cmp = c_timeCompare(newExpiryTime, lease->expiryTime); /* Always replace the current expiry time with the new expiryTime */ lease->expiryTime = newExpiryTime; /* If the new expiryTime is earlier then the previous expiryTime. Then * this means the observers must be notified so they can take the * earlier expiryTime into account */ if (cmp == C_LT) { /* Collect all observers, so they can be notified of the lease change * Must do a seperate collect as the lease mutex is 'lower' then the * leaseManager mutex. So to prevent deadlock we can not directly notify * the lease manager as we walk the collection */ if(lease->observers) { c_walk(lease->observers, v_leaseCollectObservers, &observers); } v_leaseUnlock(lease); if(observers) { observer = v_leaseManager(c_iterTakeFirst(observers)); while (observer != NULL) { v_leaseManagerNotify( observer, lease, V_EVENT_LEASE_RENEWED); c_free(observer); observer = v_leaseManager(c_iterTakeFirst(observers)); } c_iterFree(observers); } } else { /* No need to notify observers, the new expiryTime is not earlier * then what it was before. */ v_leaseUnlock(lease); } } }