mirror of
https://github.com/urbit/shrub.git
synced 2024-12-29 23:23:52 +03:00
vere: WIP adds auto.c (i/o driver abstraction)
This commit is contained in:
parent
13c51e2fe6
commit
7226b7b21d
221
pkg/urbit/vere/auto.c
Normal file
221
pkg/urbit/vere/auto.c
Normal file
@ -0,0 +1,221 @@
|
||||
/* vere/auto.c
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include <gmp.h>
|
||||
#include <sigsegv.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <uv.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "all.h"
|
||||
#include "vere/vere.h"
|
||||
|
||||
typedef struct _u3_ovum {
|
||||
struct _u3_auto* car_u; // backpointer to i/o driver
|
||||
void* vod_p; // context
|
||||
c3_l msc_l; // ms to timeout
|
||||
u3_noun tag; // target
|
||||
u3_noun pax; // wire
|
||||
u3_noun fav; // card
|
||||
struct _u3_ovum* pre_u; // previous ovum
|
||||
struct _u3_ovum* nex_u; // next ovum
|
||||
} u3_ovum;
|
||||
|
||||
typedef struct _u3_auto {
|
||||
c3_m nam_m;
|
||||
c3_o liv_o;
|
||||
struct {
|
||||
void (*init_f)(struct _u3_auto*);
|
||||
void (*talk_f)(struct _u3_auto*);
|
||||
c3_o (*fete_f)(struct _u3_auto*, u3_noun pax, u3_noun fav); // RETAIN
|
||||
void (*exit_f)(struct _u3_auto*); // XX close_cb?
|
||||
} io;
|
||||
struct {
|
||||
void (*drop_f)(struct _u3_auto*, void*);
|
||||
void (*work_f)(struct _u3_auto*, void*);
|
||||
void (*done_f)(struct _u3_auto*, void*);
|
||||
void (*swap_f)(struct _u3_auto*, void*);
|
||||
void (*bail_f)(struct _u3_auto*, void*);
|
||||
} ev;
|
||||
struct _u3_ovum* ent_u;
|
||||
struct _u3_ovum* ext_u;
|
||||
struct _u3_auto* nex_u;
|
||||
} u3_auto;
|
||||
|
||||
/* u3_auto_init(): initialize all drivers
|
||||
*/
|
||||
void
|
||||
u3_auto_init(u3_auto* car_u)
|
||||
{
|
||||
while ( car_u ) {
|
||||
car_u->io.init_f(car_u);
|
||||
car_u = car_u->nex_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_auto_talk(): start all drivers
|
||||
*/
|
||||
void
|
||||
u3_auto_talk(u3_auto* car_u)
|
||||
{
|
||||
while ( car_u ) {
|
||||
car_u->io.talk_f(car_u);
|
||||
car_u = car_u->nex_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_auto_exit(): close all drivers
|
||||
*/
|
||||
void
|
||||
u3_auto_exit(u3_auto* car_u)
|
||||
{
|
||||
while ( car_u ) {
|
||||
car_u->io.exit_f(car_u);
|
||||
car_u = car_u->nex_u;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3_auto_live(): check if all drivers are live.
|
||||
*/
|
||||
c3_o
|
||||
u3_auto_live(u3_auto* car_u)
|
||||
{
|
||||
while ( car_u ) {
|
||||
if ( c3n == car_u->liv_o ) {
|
||||
return c3n;
|
||||
}
|
||||
|
||||
car_u = car_u->nex_u;
|
||||
}
|
||||
|
||||
return c3y;
|
||||
}
|
||||
|
||||
/* u3_auto_plan(): create and enqueue an ovum
|
||||
*/
|
||||
u3_ovum*
|
||||
u3_auto_plan(u3_auto* car_u,
|
||||
void* vod_p,
|
||||
c3_l msc_l,
|
||||
u3_noun tag,
|
||||
u3_noun pax,
|
||||
u3_noun fav)
|
||||
{
|
||||
u3_ovum* egg_u = c3_malloc(sizeof(*egg_u));
|
||||
egg_u->car_u = car_u;
|
||||
egg_u->vod_p = vod_p;
|
||||
egg_u->msc_l = msc_l;
|
||||
egg_u->tag = tag;
|
||||
egg_u->pax = pax;
|
||||
egg_u->fav = fav;
|
||||
|
||||
if ( !car_u->ent_u ) {
|
||||
c3_assert(!car_u->ext_u);
|
||||
|
||||
egg_u->pre_u = egg_u->nex_u = 0;
|
||||
car_u->ent_u = car_u->ext_u = egg_u;
|
||||
}
|
||||
else {
|
||||
egg_u->nex_u = 0;
|
||||
egg_u->pre_u = car_u->ent_u;
|
||||
|
||||
car_u->ent_u->nex_u = egg_u;
|
||||
car_u->ent_u = egg_u;
|
||||
}
|
||||
|
||||
return egg_u;
|
||||
}
|
||||
|
||||
|
||||
/* u3_auto_drop(): dequeue and dispose an ovum.
|
||||
*/
|
||||
void
|
||||
u3_auto_drop(u3_auto* car_u, u3_ovum* egg_u)
|
||||
{
|
||||
if ( egg_u->pre_u ) {
|
||||
egg_u->pre_u->nex_u = egg_u->nex_u;
|
||||
}
|
||||
|
||||
if ( egg_u->nex_u ) {
|
||||
egg_u->nex_u->pre_u = egg_u->pre_u;
|
||||
}
|
||||
|
||||
// notify driver if not self-caused
|
||||
//
|
||||
if ( egg_u->car_u && ( car_u != egg_u->car_u ) ) {
|
||||
egg_u->car_u->ev.drop_f(egg_u->car_u, egg_u->vod_p);
|
||||
}
|
||||
|
||||
u3z(egg_u->tag);
|
||||
u3z(egg_u->pax);
|
||||
u3z(egg_u->fav);
|
||||
c3_free(egg_u);
|
||||
}
|
||||
|
||||
/* u3_auto_next(): select an ovum and dequeue.
|
||||
*/
|
||||
u3_ovum*
|
||||
u3_auto_next(u3_auto* car_u)
|
||||
{
|
||||
u3_ovum* egg_u = 0;
|
||||
|
||||
while ( car_u ) {
|
||||
if ( car_u->ext_u ) {
|
||||
egg_u = car_u->ext_u;
|
||||
|
||||
c3_assert( !egg_u->pre_u );
|
||||
c3_assert( egg_u->nex_u );
|
||||
|
||||
egg_u->nex_u->pre_u = 0;
|
||||
car_u->ext_u = egg_u->nex_u;
|
||||
egg_u->nex_u = 0;
|
||||
|
||||
// XX better name?
|
||||
//
|
||||
egg_u->car_u->ev.work_f(egg_u->car_u, egg_u->vod_p);
|
||||
|
||||
return egg_u;
|
||||
}
|
||||
|
||||
car_u = car_u->nex_u;
|
||||
}
|
||||
|
||||
return egg_u;
|
||||
}
|
||||
|
||||
/* u3_auto_fete(): route effects to a linked driver
|
||||
*/
|
||||
void
|
||||
u3_auto_fete(u3_auto* car_u, u3_noun act)
|
||||
{
|
||||
u3_noun pax, fav, fec;
|
||||
u3_auto* rac_u = car_u;
|
||||
|
||||
while ( u3_nul != act ) {
|
||||
fec = u3h(act);
|
||||
u3x_cell(fec, &pax, &fav);
|
||||
|
||||
while ( c3n == car_u->io.fete_f(car_u, pax, fav) ) {
|
||||
if ( !car_u->nex_u ) {
|
||||
// reck_kick_norm
|
||||
// "kick: lost"
|
||||
break;
|
||||
}
|
||||
else {
|
||||
car_u = car_u->nex_u;
|
||||
}
|
||||
}
|
||||
|
||||
car_u = rac_u;
|
||||
act = u3t(act);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user