📄 tmulti.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/socktest/tmulti.c,v 1.1.1.1 2001/11/05 17:49:14 tneale Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** * Copyright 1998-1999 Integrated Systems, Inc. * All rights reserved. ****************************************************************************//* * $Log: tmulti.c,v $ * Revision 1.1.1.1 2001/11/05 17:49:14 tneale * Tornado shuffle * * Revision 1.3 2001/05/24 20:32:31 paul * CAD-UL compiler is picky. * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*//* * Test multiple threads sharing access to a descriptor. * * interesting call pairs: * * UDP * recv/recv (all possible combos) * send/send * select/select * * close/recv * close/send * close/select * * * we need at least three threads.. * thread 1 (master) spawns others, waits for them to check in, * delays a hair, then does something to kick them forward.. */#include "test.h"enum mt_func { MT_RECV, MT_RECVCLOSE, MT_RECVFROM, MT_RECVMSG, MT_SEND, MT_SENDTO, MT_SENDMSG, MT_CLOSE, MT_SELECT};struct task_fun { int ready; int idx; enum mt_func func; int fd; etc_thread_t thread; int fail;};void *test_task_doer(void *arg){ struct task_fun *t = arg; char buf[100]; int cnt; t->ready = 1; switch(t->func) { case MT_RECV: if (verbose) printf("doer%d: about to call recv\n", t->idx); cnt = recv(t->fd, buf, sizeof(buf), 0); if (verbose) printf("doer%d: recv returned %d/%d\n", t->idx, cnt, errno); if (cnt >= 0) t->fail = 0; break; case MT_RECVCLOSE: if (verbose) printf("doer%d: about to call recv\n", t->idx); cnt = recv(t->fd, buf, sizeof(buf), 0); if (verbose) printf("doer%d: recv returned %d/%d\n", t->idx, cnt, errno); /* if we get here, we didn't fail (wedge up) */ t->fail = 0; break; default: t->fail = 1; break; } ETC_THD_EXIT(); return 0;}void test_task_kick(int fd, enum mt_func func, struct sockaddr_in *sp){ int altfd, ret; unsigned long loopback = 0x7f000001; switch(func) { case MT_RECVCLOSE: close(fd); break; case MT_RECV: altfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (altfd < 0) { test_fail(0, "multitask kick", "socket"); return; } if (verbose) printf("kicker: about to send\n"); sp->sin_addr.s_addr = htonl(loopback); ret = sendto(altfd, "foo", 3, 0, (struct sockaddr *)sp, sizeof(*sp)); if (ret < 0) { if (verbose) printf("sendto returned %d/%d\n", ret, errno); perror("sendto"); } if (verbose) printf("done with send\n"); close(altfd); break; default: test_fail(0, "multitask kick", "unknown test"); break; }}void test_one_multitask(char *what, enum mt_func func, int nt){ int i; int testfd; static struct sockaddr_in s_in; int len; struct task_fun task[10]; testfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (testfd < 0) { test_fail(0, "multitask setup", "socket"); goto out; } memset(&s_in, 0, sizeof(s_in)); s_in.sin_family = AF_INET; if (bind (testfd, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) { test_fail(0, "multitask setup", "bind"); goto out; } len = sizeof(s_in); if (getsockname (testfd, (struct sockaddr *)&s_in, &len) < 0) { test_fail(0, "multitask setup", "getsockname"); goto out; } for (i=0; i< nt; i++) { task[i].fd = testfd; task[i].ready = 0; task[i].fail = -1; task[i].func = func; task[i].idx = i; if (verbose) printf("%s%d: Starting task %d\n", what, nt, i); ETC_THD_CREATE(&task[i].thread, test_task_doer, (void *)&task[i]); } ETC_THD_YIELD(); for (i=0; i< nt;i++) { if (verbose) printf("waiting for task %d to become ready\n", i); while (task[i].ready == 0) ETC_THD_YIELD(); if (verbose) printf("task %d ready\n", i); } ETC_THD_YIELD(); if (verbose) printf("%s%d: kicking tasks..\n", what, nt); for (i=0; i<nt; i++) { test_task_kick (testfd, func, &s_in); ETC_THD_YIELD(); } for (i=0; i< nt;i++) { if (verbose) printf("waiting for task %d to exit\n", i); ETC_THD_WAIT(task[i].thread); test("", "multi_recv", task[i].fail, 0, 0); } if (verbose) printf("%s%d: Done\n", what, nt); /* strand any threads.. */ out: (void)close(testfd);}void test_multitask(int flags){ int nt; for (nt = 1; nt < 10; nt++) { test_one_multitask("recvclose", MT_RECVCLOSE, nt); } for (nt = 1; nt < 10; nt++) { test_one_multitask("recv", MT_RECV, nt); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -