mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
linkedlist helpers
This commit is contained in:
parent
05d74e45dc
commit
e2a926de2f
2 changed files with 104 additions and 43 deletions
|
@ -4196,6 +4196,74 @@ lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr,
|
|||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* lws_start_foreach_ll(): linkedlist iterator helper start
|
||||
*
|
||||
* \param type: type of iteration, eg, struct xyz *
|
||||
* \param it: iterator var name to create
|
||||
* \param start: start of list
|
||||
*
|
||||
* This helper creates an iterator and starts a while (it) {
|
||||
* loop. The iterator runs through the linked list starting at start and
|
||||
* ends when it gets a NULL.
|
||||
* The while loop should be terminated using lws_start_foreach_ll().
|
||||
*/
|
||||
#define lws_start_foreach_ll(type, it, start)\
|
||||
{ \
|
||||
type it = start; \
|
||||
while (it) {
|
||||
|
||||
/**
|
||||
* lws_end_foreach_ll(): linkedlist iterator helper end
|
||||
*
|
||||
* \param it: same iterator var name given when starting
|
||||
* \param nxt: member name in the iterator pointing to next list element
|
||||
*
|
||||
* This helper is the partner for lws_start_foreach_ll() that ends the
|
||||
* while loop.
|
||||
*/
|
||||
|
||||
#define lws_end_foreach_ll(it, nxt) \
|
||||
it = it->nxt; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* lws_start_foreach_llp(): linkedlist pointer iterator helper start
|
||||
*
|
||||
* \param type: type of iteration, eg, struct xyz **
|
||||
* \param it: iterator var name to create
|
||||
* \param start: start of list
|
||||
*
|
||||
* This helper creates an iterator and starts a while (it) {
|
||||
* loop. The iterator runs through the linked list starting at the
|
||||
* address of start and ends when it gets a NULL.
|
||||
* The while loop should be terminated using lws_start_foreach_llp().
|
||||
*
|
||||
* This helper variant iterates using a pointer to the previous linked-list
|
||||
* element. That allows you to easily delete list members by rewriting the
|
||||
* previous pointer to the element's next pointer.
|
||||
*/
|
||||
#define lws_start_foreach_llp(type, it, start)\
|
||||
{ \
|
||||
type it = &(start); \
|
||||
while (*(it)) {
|
||||
|
||||
/**
|
||||
* lws_end_foreach_llp(): linkedlist pointer iterator helper end
|
||||
*
|
||||
* \param it: same iterator var name given when starting
|
||||
* \param nxt: member name in the iterator pointing to next list element
|
||||
*
|
||||
* This helper is the partner for lws_start_foreach_llp() that ends the
|
||||
* while loop.
|
||||
*/
|
||||
|
||||
#define lws_end_foreach_llp(it, nxt) \
|
||||
it = &(*(it))->nxt; \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* lws_snprintf(): snprintf that truncates the returned length too
|
||||
*
|
||||
|
|
|
@ -68,13 +68,12 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct per_session_data__lws_mirror *pss =
|
||||
(struct per_session_data__lws_mirror *)user, **ppss,
|
||||
*pss1;
|
||||
(struct per_session_data__lws_mirror *)user;
|
||||
struct per_vhost_data__lws_mirror *v =
|
||||
(struct per_vhost_data__lws_mirror *)
|
||||
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi));
|
||||
struct lws_mirror_instance *mi, **pmi;
|
||||
struct lws_mirror_instance *mi = NULL;
|
||||
char name[30];
|
||||
int n, m, count_mi = 0;
|
||||
|
||||
|
@ -95,17 +94,16 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
|
||||
/* is there already a mirror instance of this name? */
|
||||
|
||||
mi = v->mi_list;
|
||||
while (mi) {
|
||||
if (!strcmp(name, mi->name)) {
|
||||
lwsl_notice("Joining existing mi %p '%s'\n",
|
||||
mi, name);
|
||||
/* yes... we will join it */
|
||||
break;
|
||||
}
|
||||
lws_start_foreach_ll(struct lws_mirror_instance *,
|
||||
mi1, v->mi_list) {
|
||||
count_mi++;
|
||||
mi = mi->next;
|
||||
}
|
||||
if (strcmp(name, mi1->name))
|
||||
continue;
|
||||
/* yes... we will join it */
|
||||
lwsl_notice("Joining existing mi %p '%s'\n", mi1, name);
|
||||
mi = mi1;
|
||||
break;
|
||||
} lws_end_foreach_ll(mi1, next);
|
||||
|
||||
if (!mi) {
|
||||
|
||||
|
@ -123,7 +121,6 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
strcpy(mi->name, name);
|
||||
mi->ringbuffer_head = 0;
|
||||
|
||||
|
||||
lwsl_notice("Created new mi %p '%s'\n", mi, name);
|
||||
}
|
||||
|
||||
|
@ -147,42 +144,40 @@ callback_lws_mirror(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
mi = pss->mi;
|
||||
if (!mi)
|
||||
break;
|
||||
ppss = &mi->same_mi_pss_list;
|
||||
|
||||
while (*ppss) {
|
||||
lws_start_foreach_llp(struct per_session_data__lws_mirror **,
|
||||
ppss, mi->same_mi_pss_list) {
|
||||
if (*ppss == pss) {
|
||||
|
||||
*ppss = pss->same_mi_pss_list;
|
||||
break;
|
||||
}
|
||||
} lws_end_foreach_llp(ppss, same_mi_pss_list);
|
||||
|
||||
ppss = &(*ppss)->same_mi_pss_list;
|
||||
}
|
||||
pss->mi = NULL;
|
||||
|
||||
if (!mi->same_mi_pss_list) {
|
||||
if (mi->same_mi_pss_list)
|
||||
break;
|
||||
|
||||
/* last pss unbound from mi... delete mi */
|
||||
/* last pss unbound from mi... delete mi */
|
||||
|
||||
pmi = &v->mi_list;
|
||||
while (*pmi) {
|
||||
if (*pmi == mi) {
|
||||
*pmi = (*pmi)->next;
|
||||
lws_start_foreach_llp(struct lws_mirror_instance **,
|
||||
pmi, v->mi_list) {
|
||||
if (*pmi != mi)
|
||||
continue;
|
||||
|
||||
if (!pss->mi)
|
||||
break;
|
||||
lwsl_info("%s: mirror protocol cleaning up %p\n", __func__, v);
|
||||
for (n = 0; n < ARRAY_SIZE(pss->mi->ringbuffer); n++)
|
||||
if (pss->mi->ringbuffer[n].payload) {
|
||||
free(pss->mi->ringbuffer[n].payload);
|
||||
pss->mi->ringbuffer[n].payload = NULL;
|
||||
}
|
||||
*pmi = (*pmi)->next;
|
||||
|
||||
free(mi);
|
||||
break;
|
||||
lwsl_info("%s: mirror cleaniup %p\n", __func__, v);
|
||||
for (n = 0; n < ARRAY_SIZE(mi->ringbuffer); n++)
|
||||
if (mi->ringbuffer[n].payload) {
|
||||
free(mi->ringbuffer[n].payload);
|
||||
mi->ringbuffer[n].payload = NULL;
|
||||
}
|
||||
count_mi++;
|
||||
pmi = &(*pmi)->next;
|
||||
}
|
||||
}
|
||||
|
||||
free(mi);
|
||||
break;
|
||||
} lws_end_foreach_llp(pmi, next);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -257,12 +252,10 @@ done:
|
|||
* ask for WRITABLE callback for every wsi bound to this
|
||||
* mirror instance
|
||||
*/
|
||||
|
||||
pss1 = pss->mi->same_mi_pss_list;
|
||||
while (pss1) {
|
||||
lws_start_foreach_ll(struct per_session_data__lws_mirror *,
|
||||
pss1, pss->mi->same_mi_pss_list) {
|
||||
lws_callback_on_writable(pss1->wsi);
|
||||
pss1 = pss1->same_mi_pss_list;
|
||||
}
|
||||
} lws_end_foreach_ll(pss1, same_mi_pss_list);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue