///@{
/**
+ * 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
*
* \param str: destination buffer
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;
/* 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) {
strcpy(mi->name, name);
mi->ringbuffer_head = 0;
-
lwsl_notice("Created new mi %p '%s'\n", mi, name);
}
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;
* 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: