Skip to content

Commit

Permalink
stock/BasicStock: convert StockHandler to BasicStock virtual method
Browse files Browse the repository at this point in the history
This moves the complexity of the DeferEvent to class MapStock, its
only user so far.
  • Loading branch information
MaxKellermann committed Oct 16, 2023
1 parent 0c7e640 commit 106c42d
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 68 deletions.
28 changes: 9 additions & 19 deletions src/stock/BasicStock.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ BasicStock::FadeAll() noexcept
i.Fade();

ClearIdle();
ScheduleCheckEmpty();
CheckEmpty();

// TODO: restart the "num_create" list?
}
Expand All @@ -38,15 +38,8 @@ BasicStock::Shutdown() noexcept
void
BasicStock::CheckEmpty() noexcept
{
if (IsEmpty() && handler != nullptr)
handler->OnStockEmpty(*this);
}

void
BasicStock::ScheduleCheckEmpty() noexcept
{
if (IsEmpty() && handler != nullptr)
empty_event.Schedule();
if (IsEmpty())
OnEmpty();
}


Expand Down Expand Up @@ -106,14 +99,11 @@ BasicStock::ClearEventCallback() noexcept

BasicStock::BasicStock(EventLoop &event_loop, StockClass &_cls,
const char *_name, std::size_t _max_idle,
Event::Duration _clear_interval,
StockHandler *_handler) noexcept
Event::Duration _clear_interval) noexcept
:cls(_cls),
name(_name),
max_idle(_max_idle),
clear_interval(_clear_interval),
handler(_handler),
empty_event(event_loop, BIND_THIS_METHOD(CheckEmpty)),
cleanup_event(event_loop, BIND_THIS_METHOD(CleanupEventCallback)),
clear_event(event_loop, BIND_THIS_METHOD(ClearEventCallback))
{
Expand Down Expand Up @@ -165,7 +155,7 @@ BasicStock::GetIdle() noexcept
delete &item;
}

ScheduleCheckEmpty();
CheckEmpty();
return nullptr;
}

Expand Down Expand Up @@ -221,7 +211,7 @@ BasicStock::ItemCreateError(StockGetHandler &get_handler,
assert(num_create > 0);
--num_create;

ScheduleCheckEmpty();
CheckEmpty();

get_handler.OnStockItemError(ep);
}
Expand All @@ -232,7 +222,7 @@ BasicStock::ItemCreateAborted() noexcept
assert(num_create > 0);
--num_create;

ScheduleCheckEmpty();
CheckEmpty();
}

PutAction
Expand All @@ -250,7 +240,7 @@ BasicStock::Put(StockItem &item, PutAction action) noexcept
if (action == PutAction::DESTROY ||
item.IsFading() || !item.Release()) {
delete &item;
ScheduleCheckEmpty();
CheckEmpty();
return PutAction::DESTROY;
} else {
InjectIdle(item);
Expand Down Expand Up @@ -287,7 +277,7 @@ BasicStock::ItemIdleDisconnect(StockItem &item) noexcept
UnscheduleCleanup();

delete &item;
ScheduleCheckEmpty();
CheckEmpty();
}

void
Expand Down
32 changes: 9 additions & 23 deletions src/stock/BasicStock.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "Request.hxx"
#include "Stats.hxx"
#include "event/CoarseTimerEvent.hxx"
#include "event/DeferEvent.hxx"
#include "util/DeleteDisposer.hxx"
#include "util/IntrusiveList.hxx"

Expand All @@ -23,15 +22,6 @@ class BasicStock;
class StockClass;
class StockGetHandler;

class StockHandler {
public:
/**
* The stock has become empty. It is safe to delete it from
* within this method.
*/
virtual void OnStockEmpty(BasicStock &stock) noexcept = 0;
};

/**
* Objects in stock. May be used for connection pooling.
*
Expand All @@ -52,14 +42,6 @@ private:

const Event::Duration clear_interval;

StockHandler *const handler;

/**
* This event is used to move the "empty" check out of the current
* stack, to invoke the handler method in a safe environment.
*/
DeferEvent empty_event;

CoarseTimerEvent cleanup_event;
CoarseTimerEvent clear_event;

Expand All @@ -82,16 +64,15 @@ public:
*/
BasicStock(EventLoop &event_loop, StockClass &cls,
const char *name, std::size_t max_idle,
Event::Duration _clear_interval,
StockHandler *handler=nullptr) noexcept;
Event::Duration _clear_interval) noexcept;

~BasicStock() noexcept;

BasicStock(const BasicStock &) = delete;
BasicStock &operator=(const BasicStock &) = delete;

EventLoop &GetEventLoop() const noexcept override {
return empty_event.GetEventLoop();
return cleanup_event.GetEventLoop();
}

StockClass &GetClass() noexcept {
Expand Down Expand Up @@ -136,7 +117,7 @@ public:

ClearIdleIf(predicate);

ScheduleCheckEmpty();
CheckEmpty();
// TODO: restart the "num_create" list?
}

Expand All @@ -160,12 +141,17 @@ protected:
return busy.size() + num_create;
}

/**
* The stock has become empty. It is not safe to delete it
* from within this method.
*/
virtual void OnEmpty() noexcept {}

private:
/**
* Check if the stock has become empty, and invoke the handler.
*/
void CheckEmpty() noexcept;
void ScheduleCheckEmpty() noexcept;

void ScheduleClear() noexcept {
if (clear_interval > Event::Duration::zero())
Expand Down
22 changes: 9 additions & 13 deletions src/stock/MapStock.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
#include "util/DeleteDisposer.hxx"
#include "util/StringAPI.hxx"

void
StockMap::Item::OnDeferredEmpty() noexcept
{
if (IsEmpty() && !sticky)
map.Erase(*this);
}

inline size_t
StockMap::Item::Hash::operator()(const char *key) const noexcept
{
Expand Down Expand Up @@ -45,27 +52,16 @@ StockMap::Erase(Item &item) noexcept
map.erase_and_dispose(i, DeleteDisposer());
}

void
StockMap::OnStockEmpty(BasicStock &stock) noexcept
{
auto &item = static_cast<Item &>(stock);
if (item.sticky)
return;

Erase(item);
}

Stock &
StockMap::GetStock(const char *uri, void *request) noexcept
{
auto [position, inserted] = map.insert_check(uri);
if (inserted) {
auto *item = new Item(event_loop, cls,
auto *item = new Item(*this, event_loop, cls,
uri,
GetLimit(request, limit),
max_idle,
GetClearInterval(request),
this);
GetClearInterval(request));
map.insert_commit(position, *item);
return *item;
} else
Expand Down
26 changes: 19 additions & 7 deletions src/stock/MapStock.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,41 @@

#include "Stock.hxx"
#include "event/Chrono.hxx"
#include "event/DeferEvent.hxx"
#include "util/IntrusiveHashSet.hxx"
#include "util/StringAPI.hxx"

#include <cassert>
#include <concepts> // for std::predicate
#include <cstddef>

/**
* A hash table of any number of Stock objects, each with a different
* URI.
*/
class StockMap : StockHandler {
class StockMap {
struct Item final : IntrusiveHashSetHook<IntrusiveHookMode::NORMAL>, Stock {
StockMap &map;

DeferEvent defer_empty{GetEventLoop(), BIND_THIS_METHOD(OnDeferredEmpty)};

bool sticky = false;

template<typename... Args>
explicit Item(StockMap &_map, Args&&... args) noexcept
:Stock(std::forward<Args>(args)...), map(_map) {}

template<typename... Args>
explicit Item(Args&&... args) noexcept
:Stock(std::forward<Args>(args)...) {}

protected:
virtual void OnEmpty() noexcept override {
defer_empty.Schedule();
}

private:
void OnDeferredEmpty() noexcept;

public:
struct Hash {
[[gnu::pure]]
size_t operator()(const char *key) const noexcept;
Expand Down Expand Up @@ -158,8 +174,4 @@ protected:
virtual Event::Duration GetClearInterval([[maybe_unused]] const void *request) const noexcept {
return clear_interval;
}

private:
/* virtual methods from class StockHandler */
void OnStockEmpty(BasicStock &stock) noexcept override;
};
6 changes: 2 additions & 4 deletions src/stock/Stock.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,10 @@ Stock::ScheduleRetryWaiting() noexcept

Stock::Stock(EventLoop &event_loop, StockClass &_cls,
const char *_name, std::size_t _limit, std::size_t _max_idle,
Event::Duration _clear_interval,
StockHandler *_handler) noexcept
Event::Duration _clear_interval) noexcept
:BasicStock(event_loop, _cls, _name,
_max_idle,
_clear_interval,
_handler),
_clear_interval),
limit(_limit),
retry_event(event_loop, BIND_THIS_METHOD(RetryWaiting))
{
Expand Down
3 changes: 1 addition & 2 deletions src/stock/Stock.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ public:
*/
Stock(EventLoop &event_loop, StockClass &cls,
const char *name, std::size_t limit, std::size_t max_idle,
Event::Duration _clear_interval,
StockHandler *handler=nullptr) noexcept;
Event::Duration _clear_interval) noexcept;

~Stock() noexcept;

Expand Down

0 comments on commit 106c42d

Please sign in to comment.