mirror of
https://github.com/ohwgiles/laminar.git
synced 2024-10-27 20:34:20 +00:00
implement general-purpose locks
This commit is contained in:
parent
f42325b472
commit
ab99af7ca7
@ -158,6 +158,14 @@ int main(int argc, char** argv) {
|
|||||||
auto response = req.send().wait(waitScope);
|
auto response = req.send().wait(waitScope);
|
||||||
if(response.getResult() != LaminarCi::JobResult::SUCCESS)
|
if(response.getResult() != LaminarCi::JobResult::SUCCESS)
|
||||||
return EFAILED;
|
return EFAILED;
|
||||||
|
} else if(strcmp(argv[1], "lock") == 0) {
|
||||||
|
auto req = laminar.lockRequest();
|
||||||
|
req.setLockName(argv[2]);
|
||||||
|
req.send().wait(waitScope);
|
||||||
|
} else if(strcmp(argv[1], "release") == 0) {
|
||||||
|
auto req = laminar.releaseRequest();
|
||||||
|
req.setLockName(argv[2]);
|
||||||
|
req.send().wait(waitScope);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown comand %s\n", argv[1]);
|
fprintf(stderr, "Unknown comand %s\n", argv[1]);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
@ -6,6 +6,8 @@ interface LaminarCi {
|
|||||||
start @1 (jobName :Text, params :List(JobParam)) -> (result :JobResult);
|
start @1 (jobName :Text, params :List(JobParam)) -> (result :JobResult);
|
||||||
pend @2 (jobName :Text, buildNum :UInt32) -> (result :JobResult);
|
pend @2 (jobName :Text, buildNum :UInt32) -> (result :JobResult);
|
||||||
set @3 (jobName :Text, buildNum :UInt32, param :JobParam) -> (result :MethodResult);
|
set @3 (jobName :Text, buildNum :UInt32, param :JobParam) -> (result :MethodResult);
|
||||||
|
lock @4 (lockName :Text) -> ();
|
||||||
|
release @5 (lockName :Text) -> ();
|
||||||
|
|
||||||
struct JobParam {
|
struct JobParam {
|
||||||
name @0 :Text;
|
name @0 :Text;
|
||||||
|
@ -75,6 +75,18 @@ LaminarCi::JobResult fromRunState(RunState state) {
|
|||||||
// As such, it implements the pure virtual interface generated from
|
// As such, it implements the pure virtual interface generated from
|
||||||
// laminar.capnp with calls to the LaminarInterface
|
// laminar.capnp with calls to the LaminarInterface
|
||||||
class RpcImpl : public LaminarCi::Server {
|
class RpcImpl : public LaminarCi::Server {
|
||||||
|
private:
|
||||||
|
struct Lock {
|
||||||
|
Lock() : paf(kj::newPromiseAndFulfiller<void>()) {}
|
||||||
|
void release() {
|
||||||
|
paf.fulfiller->fulfill();
|
||||||
|
}
|
||||||
|
kj::Promise<void> takePromise() { return std::move(paf.promise); }
|
||||||
|
private:
|
||||||
|
kj::PromiseFulfillerPair<void> paf;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RpcImpl(LaminarInterface& l) :
|
RpcImpl(LaminarInterface& l) :
|
||||||
LaminarCi::Server(),
|
LaminarCi::Server(),
|
||||||
@ -143,9 +155,36 @@ public:
|
|||||||
return kj::READY_NOW;
|
return kj::READY_NOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Take a named lock
|
||||||
|
kj::Promise<void> lock(LockContext context) override {
|
||||||
|
std::string lockName = context.getParams().getLockName();
|
||||||
|
LLOG(INFO, "RPC lock", lockName);
|
||||||
|
auto& lockList = locks[lockName];
|
||||||
|
lockList.emplace_back(Lock{});
|
||||||
|
if(lockList.size() == 1)
|
||||||
|
lockList.front().release();
|
||||||
|
return lockList.back().takePromise();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release a named lock
|
||||||
|
kj::Promise<void> release(ReleaseContext context) override {
|
||||||
|
std::string lockName = context.getParams().getLockName();
|
||||||
|
LLOG(INFO, "RPC release", lockName);
|
||||||
|
auto& lockList = locks[lockName];
|
||||||
|
if(lockList.size() == 0) {
|
||||||
|
LLOG(INFO, "Attempt to release unheld lock", lockName);
|
||||||
|
return kj::READY_NOW;
|
||||||
|
}
|
||||||
|
lockList.erase(lockList.begin());
|
||||||
|
if(lockList.size() > 0)
|
||||||
|
lockList.front().release();
|
||||||
|
return kj::READY_NOW;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LaminarInterface& laminar;
|
LaminarInterface& laminar;
|
||||||
kj::LowLevelAsyncIoProvider* asyncio;
|
kj::LowLevelAsyncIoProvider* asyncio;
|
||||||
|
std::unordered_map<std::string, std::list<Lock>> locks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user