1 // Tee: read input channel and write to two output channels
13 typedef struct tee_s tee_t
[1];
14 typedef struct tee_s
*tee_ptr
;
16 static void *branch_loop(cf_t cf
) {
17 tee_ptr t
= cf_data(cf
);
21 cf_put_int(t
->parent
, t
->n
); // Causes parent to put to cf.
24 cf_put_int(t
->parent
, -1 - t
->n
); // Notify parent of our destruction.
30 struct parent_data_s
{
34 typedef struct parent_data_s parent_data_t
[1];
35 typedef struct parent_data_s
*parent_data_ptr
;
37 // TODO: Join after destruction.
38 static void *parent_loop(cf_t cf
) {
41 struct backlog_s
*next
;
43 typedef struct backlog_s
*backlog_ptr
;
53 parent_data_ptr pd
= cf_data(cf
);
57 int k
= mpz_get_ui(z
);
61 backlog_ptr pnext
= head
[k
], p
;
68 if (!pd
->kid
[1-k
]) break;
71 backlog_ptr p
= head
[k
];
76 if (!head
[k
]) last
[k
] = NULL
;
80 backlog_ptr p
= malloc(sizeof(*p
));
84 if (last
[1-k
]) last
[1-k
]->next
= p
;
86 if (!head
[1-k
]) head
[1-k
] = p
;
90 cf_put(pd
->kid
[k
], z
);
96 cf_t
cf_new_parent(cf_t in
) {
97 parent_data_ptr p
= malloc(sizeof(*p
));
101 return cf_new(parent_loop
, p
);
104 cf_t
cf_new_branch(cf_t parent
, int n
) {
105 tee_ptr t
= malloc(sizeof(*t
));
108 parent_data_ptr p
= cf_data(parent
);
109 cf_t res
= cf_new(branch_loop
, t
);
114 void cf_tee(cf_t
*out_array
, cf_t in
) {
115 cf_t parent
= cf_new_parent(in
);
116 out_array
[0] = cf_new_branch(parent
, 0);
117 out_array
[1] = cf_new_branch(parent
, 1);