Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
lihuiba committed Jan 22, 2024
1 parent 9fcbfa3 commit 81714c5
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 47 deletions.
22 changes: 9 additions & 13 deletions common/expirecontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,24 @@ limitations under the License.
*/

#include "expirecontainer.h"

#include <photon/thread/thread.h>

ExpireContainerBase::ExpireContainerBase(uint64_t expiration,
ExpireContainerBase::ExpireContainerBase(uint64_t lifespan,
uint64_t timer_cycle)
: _expiration(expiration),
: _lifespan(lifespan),
_timer(std::max(static_cast<uint64_t>(1000), timer_cycle),
{this, &ExpireContainerBase::expire}, true, 8UL * 1024 * 1024) {}

std::pair<ExpireContainerBase::iterator, bool> ExpireContainerBase::insert(
Item* item) {
auto ExpireContainerBase::insert(Item* item) -> std::pair<iterator, bool> {
return _set.emplace(item);
}

ExpireContainerBase::iterator ExpireContainerBase::__find_prelock(
const Item& key_item) {
auto ExpireContainerBase::__find_prelock(const Item& key_item) -> iterator {
auto it = _set.find((Item*)&key_item);
return it;
}

ExpireContainerBase::iterator ExpireContainerBase::find(const Item& key_item) {
auto ExpireContainerBase::find(const Item& key_item) -> iterator {
SCOPED_LOCK(_lock);
return __find_prelock(key_item);
}
Expand Down Expand Up @@ -77,9 +74,9 @@ bool ExpireContainerBase::keep_alive(const Item& x, bool insert_if_not_exists) {
return true;
}

ObjectCacheBase::Item* ObjectCacheBase::ref_acquire(const Item& key_item,
Delegate<void, void*> ctor,
uint64_t failure_cooldown) {
auto ObjectCacheBase::ref_acquire(const Item& key_item,
Delegate<void, void*> ctor,
uint64_t failure_cooldown) -> Item* {
Base::iterator holder;
Item* item = nullptr;
expire();
Expand Down Expand Up @@ -150,8 +147,7 @@ int ObjectCacheBase::ref_release(ItemPtr item, bool recycle) {
}

// the argument `key` plays the roles of (type-erased) key
int ObjectCacheBase::release(const ObjectCacheBase::Item& key_item,
bool recycle) {
int ObjectCacheBase::release(const Item& key_item, bool recycle) {
auto item = ExpireContainerBase::TypedIterator<Item>(Base::find(key_item));
if (item == end()) return -1;
return ref_release(*item, recycle);
Expand Down
11 changes: 7 additions & 4 deletions common/expirecontainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class ExpireContainerBase : public Object {
};

intrusive_list<Item> _list;
uint64_t _expiration;
uint64_t _lifespan;
photon::Timer _timer;
photon::spinlock _lock; // protect _list/_set operations

Expand All @@ -94,7 +94,7 @@ class ExpireContainerBase : public Object {
using Set = std::unordered_set<ItemPtr, ItemHash, ItemEqual>;
Set _set;

ExpireContainerBase(uint64_t expiration, uint64_t timer_cycle);
ExpireContainerBase(uint64_t lifespan, uint64_t timer_cycle);
~ExpireContainerBase() { clear(); }

using iterator = decltype(_set)::iterator;
Expand All @@ -116,15 +116,18 @@ class ExpireContainerBase : public Object {

void enqueue(Item* item) {
_list.pop(item);
item->_timeout.timeout(_expiration);
item->_timeout.timeout(_lifespan);
_list.push_back(item);
}

public:
void clear();
uint64_t expire();
size_t size() { return _set.size(); }
size_t expiration() { return _expiration; }
size_t lifespan() { return _lifespan; }

[[deprecated("use lifespan() instead")]]
size_t expiration() { return _lifespan; }
};

template <typename KeyType, typename... Ts>
Expand Down
52 changes: 26 additions & 26 deletions common/timeout.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,39 @@ namespace photon {

extern volatile uint64_t now;

class Timeout
{
class Timeout {
protected:
uint64_t m_expiration = -1; // time of expiration, in us

public:
Timeout() = default; // never
Timeout(uint64_t x) { timeout(x); }
uint64_t timeout(uint64_t x){ return m_expire = sat_add(now, x); }
uint64_t timeout() const { return sat_sub(m_expire, now); }
operator uint64_t() const { return timeout(); }
operator bool () const { return m_expire > now; }
uint64_t timeout_us() const { return timeout(); }
uint64_t timeout_ms() const { return divide(timeout(), 1000); }
uint64_t timeout_MS() const { return divide(timeout(), 1024); } // fast approximation
uint64_t timeout_s() const { return divide(timeout(), 1000 * 1000); }
uint64_t timeout_S() const { return divide(timeout(), 1024 * 1024); } // fast approximation
uint64_t expiration() const { return m_expire; }
uint64_t expiration(uint64_t x) {
return m_expire = x; }
bool operator < (const Timeout& rhs) const {
return m_expire < rhs.m_expire; }
Timeout& operator = (uint64_t x) { timeout(x); return *this; }
Timeout() = default; // never timeout
Timeout(uint64_t x) { m_expiration = x ? sat_add(now, x) : 0; }
uint64_t timeout(uint64_t x) { return m_expiration = sat_add(now, x); }
uint64_t timeout() const { return sat_sub(m_expiration, now); }
operator uint64_t() const { return timeout(); }
bool expired() const { return (m_expiration == 0) || (m_expiration <= now); }
uint64_t timeout_us() const { return timeout(); }
uint64_t timeout_ms() const { return divide(timeout(), 1000); }
uint64_t timeout_MS() const { return divide(timeout(), 1024); } // fast approximation
uint64_t timeout_s() const { return divide(timeout(), 1000 * 1000); }
uint64_t timeout_S() const { return divide(timeout(), 1024 * 1024); } // fast approximation
uint64_t expiration() const { return m_expiration; }
uint64_t expiration(uint64_t x) { return m_expiration = x; }
Timeout& operator = (uint64_t x) { timeout(x); return *this; }
Timeout& operator = (const Timeout& rhs) = default;

bool operator < (const Timeout& rhs) const {
return m_expiration < rhs.m_expiration;
}
Timeout& timeout_at_most(uint64_t x) {
x = sat_add(now, x);
if (x < m_expire)
m_expire = x;
if (x < m_expiration)
m_expiration = x;
return *this;
}

uint64_t m_expire = -1; // time of expiration, in us

static uint64_t divide(uint64_t x, uint64_t divisor)
{
protected:
operator bool() const = delete;
static uint64_t divide(uint64_t x, uint64_t divisor) {
return (x + divisor / 2) / divisor;
}
};
Expand Down
2 changes: 1 addition & 1 deletion fs/httpfs/httpfs_v2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class HttpFile_v2 : public fs::VirtualReadOnlyFile {
op.timeout = tmo;
m_fs->get_client()->call(&op);
if (op.status_code < 0) {
if (!tmo) {
if (tmo.expired()) {
m_etimeout = true;
LOG_ERROR_RETURN(ENOENT, , "http timedout");
}
Expand Down
6 changes: 3 additions & 3 deletions thread/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,7 @@ R"(
// returns 0 if slept well (at lease `useconds`), -1 otherwise
static int thread_usleep(Timeout timeout, thread_list* waitq)
{
if (unlikely(!timeout)) {
if (unlikely(timeout.expired())) {
thread_yield();
return 0;
}
Expand Down Expand Up @@ -1286,7 +1286,7 @@ R"(
RunQ rq;
if (unlikely(!rq.current))
LOG_ERROR_RETURN(ENOSYS, -1, "Photon not initialized in this thread");
if (unlikely(!timeout))
if (unlikely(timeout.expired()))
return thread_yield(), 0;
if (unlikely(rq.current->is_shutting_down()))
return do_shutdown_usleep(timeout, rq);
Expand Down Expand Up @@ -1555,7 +1555,7 @@ R"(
return 0;
}

if (!timeout) {
if (timeout.expired()) {
errno = ETIMEDOUT;
splock.unlock();
return -1;
Expand Down

0 comments on commit 81714c5

Please sign in to comment.