COVERAGE_DEFINE(rconn_queued);
COVERAGE_DEFINE(rconn_sent);
+/* The connection states have the following meanings:
+ *
+ * - S_VOID: No connection information is configured.
+ *
+ * - S_BACKOFF: Waiting for a period of time before reconnecting.
+ *
+ * - S_CONNECTING: A connection attempt is in progress and has not yet
+ * succeeded or failed.
+ *
+ * - S_ACTIVE: A connection has been established and appears to be healthy.
+ *
+ * - S_IDLE: A connection has been established but has been idle for some
+ * time. An echo request has been sent, but no reply has yet been
+ * received.
+ *
+ * - S_DISCONNECTED: An unreliable connection has disconnected and cannot be
+ * automatically retried.
+ */
#define STATES \
STATE(VOID, 1 << 0) \
STATE(BACKOFF, 1 << 1) \
STATE(CONNECTING, 1 << 2) \
STATE(ACTIVE, 1 << 3) \
- STATE(IDLE, 1 << 4)
+ STATE(IDLE, 1 << 4) \
+ STATE(DISCONNECTED, 1 << 5)
enum state {
#define STATE(NAME, VALUE) S_##NAME = VALUE,
STATES
}
}
+static unsigned int
+timeout_DISCONNECTED(const struct rconn *rc OVS_UNUSED)
+ OVS_REQUIRES(rc->mutex)
+{
+ return UINT_MAX;
+}
+
+static void
+run_DISCONNECTED(struct rconn *rc OVS_UNUSED)
+ OVS_REQUIRES(rc->mutex)
+{
+ /* Nothing to do. */
+}
+
/* Performs whatever activities are necessary to maintain 'rc': if 'rc' is
* disconnected, attempts to (re)connect, backing off as necessary; if 'rc' is
* connected, attempts to send packets in the send queue, if any. */
bool
rconn_is_alive(const struct rconn *rconn)
{
- return rconn->state != S_VOID;
+ return rconn->state != S_VOID && rconn->state != S_DISCONNECTED;
}
/* Returns true if 'rconn' is connected, false otherwise. */
OVS_REQUIRES(rc->mutex)
{
rc->last_error = error;
+ if (rc->vconn) {
+ vconn_close(rc->vconn);
+ rc->vconn = NULL;
+ }
if (rc->reliable) {
time_t now = time_now();
if (rc->state & (S_CONNECTING | S_ACTIVE | S_IDLE)) {
rc->last_disconnected = now;
- vconn_close(rc->vconn);
- rc->vconn = NULL;
flush_queue(rc);
}
state_transition(rc, S_BACKOFF);
} else {
rc->last_disconnected = time_now();
- rconn_disconnect__(rc);
+ state_transition(rc, S_DISCONNECTED);
}
}