void acl_fiber_schedule(void) { ACL_FIBER *fiber; ACL_RING *head; acl_fiber_hook_api(1); for (;;) { head = acl_ring_pop_head(&__thread_fiber->ready); if (head == NULL) { acl_msg_info("------- NO ACL_FIBER NOW --------"); break; } fiber = ACL_RING_TO_APPL(head, ACL_FIBER, me); fiber->status = FIBER_STATUS_READY; __thread_fiber->running = fiber; __thread_fiber->switched++; fiber_swap(&__thread_fiber->original, fiber); __thread_fiber->running = NULL; } /* release dead fiber */ while ((head = acl_ring_pop_head(&__thread_fiber->dead)) != NULL) { fiber = ACL_RING_TO_APPL(head, ACL_FIBER, me); fiber_free(fiber); } acl_fiber_hook_api(0); }
static void test(void) { ACL_RING ring; acl_ring_init(&ring); for (int i = 0; i < 10; i++) { A* a = new A; a->m = i; acl_ring_prepend(&ring, &a->entry); printf("put %d\r\n", i); } printf("-------------------------------------------------------\r\n"); while (true) { ACL_RING* head = acl_ring_pop_head(&ring); if (head == NULL) break; A* a = ACL_RING_TO_APPL(head, A, entry); printf("pop %d\r\n", a->m); delete a; } exit (0); }
static void fiber_kick(int max) { ACL_RING *head; ACL_FIBER *fiber; while (max > 0) { head = acl_ring_pop_head(&__thread_fiber->dead); if (head == NULL) break; fiber = ACL_RING_TO_APPL(head, ACL_FIBER,me); fiber_free(fiber); max--; } }
void acl_fiber_switch(void) { ACL_FIBER *fiber, *current = __thread_fiber->running; ACL_RING *head; #ifdef _DEBUG acl_assert(current); #endif head = acl_ring_pop_head(&__thread_fiber->ready); if (head == NULL) { fiber_swap(current, &__thread_fiber->original); return; } fiber = ACL_RING_TO_APPL(head, ACL_FIBER, me); //fiber->status = FIBER_STATUS_READY; __thread_fiber->running = fiber; __thread_fiber->switched++; fiber_swap(current, __thread_fiber->running); }
} } int test_ring(AUT_LINE *test_line acl_unused, void *arg acl_unused) { ACL_RING_ITER ring_iter; MY_TYPE *my_type; acl_ring_init(&__ring_header); __create_ring(0, 10); printf("\nring loop printf:> len=%d\n", acl_ring_size(&__ring_header)); acl_ring_foreach(ring_iter, &__ring_header) { my_type = ACL_RING_TO_APPL(ring_iter.ptr, MY_TYPE, ring_entry); printf("name=%s, value=%s\n", my_type->name, my_type->value); } printf("\nring pop head loop printf:> len=%d\n", acl_ring_size(&__ring_header)); while (1) { ring_iter.ptr = acl_ring_pop_head(&__ring_header); if (ring_iter.ptr == NULL) break; my_type = ACL_RING_TO_APPL(ring_iter.ptr, MY_TYPE, ring_entry); printf("name=%s, value=%s\n", my_type->name, my_type->value); acl_myfree(my_type); }
/* DNS查询结果之后的回调函数 */ static void thrpool_nslookup_complete(const DNS_CTX *dns_ctx) { const char *myname = "thrpool_nslookup_complte"; SERVICE *service = (SERVICE *) dns_ctx->context; DNS_RING *list; ACL_RING *ring_ptr; CLIENT_ENTRY *entry; time_t inter, now; list = (DNS_RING *) acl_htable_find(service->dns_table, dns_ctx->domain_key); if (list == NULL) { acl_msg_warn(NULL, "%s: domain(%s) not found maybe handled", myname, dns_ctx->domain_key); return; } time(&now); inter = now - dns_ctx->begin; /* 如果查询时间过长,则给出警告信息 */ if (inter >= 5) acl_msg_warn("%s(%d): dns search time=%d, domain(%s)", myname, __LINE__, time(NULL) - dns_ctx->begin, dns_ctx->domain_key); while (1) { ring_ptr = acl_ring_pop_head(&list->ring); if (ring_ptr == NULL) break; list->nrefer--; entry = ACL_RING_TO_APPL(ring_ptr, CLIENT_ENTRY, dns_entry); entry->tm.dns_lookup = now - entry->tm.stamp; entry->tm.stamp = now; if (dns_ctx->ip_cnt <= 0) { acl_msg_error("%s(%d): dns not found domain(%s)", myname, __LINE__, dns_ctx->domain_key); if (entry->client == NULL) acl_msg_fatal("%s(%d): client null", __FILE__, __LINE__); if (entry->dns_errmsg) { /* XXX: 因为此处可能会有两处关闭 client 流的地方: * acl_aio_writen 及 forward_complete,为防止重复 * 关闭造成的内存访问非法,需要 * 在第一个可能关闭 * 的函数(acl_aio_writen)调用前提升 client 流的 * 引用值,并且在该函数返回后再恢复引用值 */ acl_aio_refer(entry->client); acl_aio_writen(entry->client, entry->dns_errmsg, (int) strlen(entry->dns_errmsg)); /* 恢复refer值 */ acl_aio_unrefer(entry->client); } entry->nslookup_notify_fn(entry, NSLOOKUP_ERR); continue; } if (acl_do_debug(20, 2)) { int i; for (i = 0; i < dns_ctx->ip_cnt; i++) acl_msg_info("%s(%d): domain(%s), ip%d(%s)", myname, __LINE__, dns_ctx->domain_key, i, dns_ctx->ip[i]); } /* 将查得的所有DNS结果都拷贝至请求对象中 */ memcpy(&entry->dns_ctx, dns_ctx, sizeof(entry->dns_ctx)); /* 下面注释部分被打开,便可以测试连接重试功能:)-- zsx, 2008.2.28 * strcpy(proxy_entry->dns_ctx.ip[1], proxy_entry->dns_ctx.ip[0]); * strcpy(proxy_entry->dns_ctx.ip[0], "127.0.0.1"); * if (proxy_entry->dns_ctx.ip_cnt < 2) * proxy_entry->dns_ctx.ip_cnt = 2; */ entry->ip_idx = 0; entry->nslookup_notify_fn(entry, NSLOOKUP_OK); } acl_htable_delete(service->dns_table, dns_ctx->domain_key, NULL); if (list->nrefer <= 0) acl_myfree(list); else acl_msg_fatal("%s(%d): list's nrefer=%d", myname, __LINE__, list->nrefer); }