core-lightning/common/io_lock.h
Christian Decker bb38541d9e common: Added a small locking mechanism to simplify how we lock IO
We've done this a number of times already where we're getting
exclusive access to either the out direction of a connection, or we
try to lock out the read side while we are responding to a previous
request. They usually are really cumbersome because we reach around to
the other direction to stop it from proceeding, or we flag our
exclusive access somewhere, and we always need to know whom to notify.

PR ElementsProject/lightning#1970 adds two new instances of this:

 - Streaming a JSON response requires that nothing else should write
   while the stream is active.
 - We also want to stop reading new requests while we are responding
   to one.

To remove the complexity of having to know whom to stop and notify
when we're done, this adds a simple `io_lock` primitive that can be
used to get exclusive access to a connection. This inverts the
requirement for notifications, since everybody registers interest in
the lock and they get notified if the lock holder releases it.
2018-10-11 01:43:55 +00:00

51 lines
1.5 KiB
C

#ifndef LIGHTNING_COMMON_IO_LOCK_H
#define LIGHTNING_COMMON_IO_LOCK_H
#include "config.h"
#include <ccan/io/io.h>
#include <ccan/tal/tal.h>
struct io_lock;
/**
* Create a new lock
*/
struct io_lock *io_lock_new(const tal_t *ctx);
/**
* Acquire lock @lock before proceeding to @next
*
* Attempts to acquire the lock before proceeding with next. If the
* lock is free this reduces to `io_always`, otherwise we put @conn in
* wait until we get notified about the lock being released.
*/
#define io_lock_acquire_out(conn, lock, next, arg) \
io_lock_acquire_out_((conn), (lock), \
typesafe_cb_preargs(struct io_plan *, void *, \
(next), (arg), \
struct io_conn *), \
(arg))
struct io_plan *io_lock_acquire_out_(struct io_conn *conn, struct io_lock *lock,
struct io_plan *(*next)(struct io_conn *,
void *),
void *arg);
#define io_lock_acquire_in(conn, lock, next, arg) \
io_lock_acquire_in_((conn), (lock), \
typesafe_cb_preargs(struct io_plan *, void *, \
(next), (arg), \
struct io_conn *), \
(arg))
struct io_plan *io_lock_acquire_in_(struct io_conn *conn, struct io_lock *lock,
struct io_plan *(*next)(struct io_conn *,
void *),
void *arg);
/**
* Release the lock and notify waiters so they can proceed.
*/
void io_lock_release(struct io_lock *lock);
#endif /* LIGHTNING_COMMON_IO_LOCK_H */