Changeset f87ede5 in rtems
- Timestamp:
- 01/15/15 13:13:19 (9 years ago)
- Branches:
- 4.11, 5, master
- Children:
- 60d39b66
- Parents:
- 51c88e8b
- git-author:
- Sebastian Huber <sebastian.huber@…> (01/15/15 13:13:19)
- git-committer:
- Sebastian Huber <sebastian.huber@…> (01/20/15 06:11:58)
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/libnetworking/kern/uipc_socket.c
r51c88e8b rf87ede5 146 146 } 147 147 148 static void 149 rtems_socket_close_notify(struct socket *so) 150 { 151 if (so->so_pgid) { 152 rtems_event_system_send(so->so_pgid, RTEMS_EVENT_SYSTEM_NETWORK_CLOSE); 153 } 154 } 155 156 static void 157 rtems_sockbuf_close_notify(struct socket *so, struct sockbuf *sb) 158 { 159 if (sb->sb_flags & SB_WAIT) { 160 rtems_event_system_send(sb->sb_sel.si_pid, 161 RTEMS_EVENT_SYSTEM_NETWORK_CLOSE); 162 } 163 164 if (sb->sb_wakeup) 165 (*sb->sb_wakeup)(so, sb->sb_wakeuparg); 166 } 167 148 168 /* 149 169 * Close a socket on last file table reference removal. … … 156 176 int s = splnet(); /* conservative */ 157 177 int error = 0; 178 179 rtems_socket_close_notify(so); 180 rtems_sockbuf_close_notify(so, &so->so_snd); 181 rtems_sockbuf_close_notify(so, &so->so_rcv); 158 182 159 183 if (so->so_options & SO_ACCEPTCONN) { … … 743 767 error = sbwait(&so->so_rcv); 744 768 if (error) { 745 sbunlock(&so->so_rcv); 769 if (error != ENXIO) 770 sbunlock(&so->so_rcv); 746 771 splx(s); 747 772 return (0); -
cpukit/libnetworking/rtems/rtems_bsdnet_internal.h
r51c88e8b rf87ede5 220 220 #define NETISR_ARP_EVENT (1L << NETISR_ARP) 221 221 #define NETISR_EVENTS (NETISR_IP_EVENT|NETISR_ARP_EVENT) 222 #if (SBWAIT_EVENT & SOSLEEP_EVENT & NETISR_EVENTS )222 #if (SBWAIT_EVENT & SOSLEEP_EVENT & NETISR_EVENTS & RTEMS_EVENT_SYSTEM_NETWORK_CLOSE) 223 223 # error "Network event conflict" 224 224 #endif -
cpukit/libnetworking/rtems/rtems_glue.c
r51c88e8b rf87ede5 433 433 } 434 434 435 static int 436 rtems_bsdnet_sleep(rtems_event_set in, rtems_interval ticks) 437 { 438 rtems_status_code sc; 439 rtems_event_set out; 440 rtems_event_set out2; 441 442 in |= RTEMS_EVENT_SYSTEM_NETWORK_CLOSE; 443 444 /* 445 * Soak up any pending events. The sleep/wakeup synchronization in the 446 * FreeBSD kernel has no memory. 447 */ 448 rtems_event_system_receive(in, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, 449 RTEMS_NO_TIMEOUT, &out); 450 451 /* 452 * Wait for the wakeup event. 453 */ 454 sc = rtems_bsdnet_event_receive(in, RTEMS_EVENT_ANY | RTEMS_WAIT, 455 ticks, &out); 456 457 /* 458 * Get additional events that may have been received between the 459 * rtems_event_system_receive() and the rtems_bsdnet_semaphore_obtain(). 460 */ 461 rtems_event_system_receive(in, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, 462 RTEMS_NO_TIMEOUT, &out2); 463 out |= out2; 464 465 if (out & RTEMS_EVENT_SYSTEM_NETWORK_CLOSE) 466 return (ENXIO); 467 468 if (sc == RTEMS_SUCCESSFUL) 469 return (0); 470 471 return (EWOULDBLOCK); 472 } 473 435 474 /* 436 475 * Wait for something to happen to a socket buffer … … 439 478 sbwait(struct sockbuf *sb) 440 479 { 441 rtems_event_set events; 442 rtems_id tid; 443 rtems_status_code sc; 444 445 /* 446 * Soak up any pending events. 447 * The sleep/wakeup synchronization in the FreeBSD 448 * kernel has no memory. 449 */ 450 rtems_event_system_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events); 480 int error; 451 481 452 482 /* 453 483 * Set this task as the target of the wakeup operation. 454 484 */ 455 rtems_task_ident (RTEMS_SELF, 0, &tid); 456 sb->sb_sel.si_pid = tid; 485 sb->sb_sel.si_pid = rtems_task_self(); 457 486 458 487 /* … … 461 490 sb->sb_flags |= SB_WAIT; 462 491 463 /* 464 * Wait for the wakeup event. 465 */ 466 sc = rtems_bsdnet_event_receive (SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, sb->sb_timeo, &events); 467 468 /* 469 * Return the status of the wait. 470 */ 471 switch (sc) { 472 case RTEMS_SUCCESSFUL: return 0; 473 case RTEMS_TIMEOUT: return EWOULDBLOCK; 474 default: return ENXIO; 475 } 492 error = rtems_bsdnet_sleep(SBWAIT_EVENT, sb->sb_timeo); 493 if (error != ENXIO) 494 sb->sb_flags &= ~SB_WAIT; 495 496 return (error); 476 497 } 477 498 … … 486 507 { 487 508 if (sb->sb_flags & SB_WAIT) { 488 sb->sb_flags &= ~SB_WAIT;489 509 rtems_event_system_send (sb->sb_sel.si_pid, SBWAIT_EVENT); 490 510 } … … 515 535 soconnsleep (struct socket *so) 516 536 { 517 rtems_event_set events; 518 rtems_id tid; 519 rtems_status_code sc; 520 521 /* 522 * Soak up any pending events. 523 * The sleep/wakeup synchronization in the FreeBSD 524 * kernel has no memory. 525 */ 526 rtems_event_system_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events); 537 int error; 527 538 528 539 /* … … 531 542 if (so->so_pgid) 532 543 rtems_panic ("Another task is already sleeping on that socket"); 533 rtems_task_ident (RTEMS_SELF, 0, &tid); 534 so->so_pgid = tid; 535 536 /* 537 * Wait for the wakeup event. 538 */ 539 sc = rtems_bsdnet_event_receive (SOSLEEP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, so->so_rcv.sb_timeo, &events); 540 541 /* 542 * Relinquish ownership of the socket. 543 */ 544 so->so_pgid = 0; 545 546 switch (sc) { 547 case RTEMS_SUCCESSFUL: return 0; 548 case RTEMS_TIMEOUT: return EWOULDBLOCK; 549 default: return ENXIO; 550 } 544 so->so_pgid = rtems_task_self(); 545 546 error = rtems_bsdnet_sleep(SOSLEEP_EVENT, so->so_rcv.sb_timeo); 547 if (error != ENXIO) 548 so->so_pgid = 0; 549 550 return (error); 551 551 } 552 552 -
cpukit/libnetworking/rtems/rtems_select.c
r51c88e8b rf87ede5 120 120 rtems_id tid; 121 121 rtems_interval then = 0, now; 122 rtems_event_set events; 122 rtems_event_set in = SBWAIT_EVENT | RTEMS_EVENT_SYSTEM_NETWORK_CLOSE; 123 rtems_event_set out; 123 124 124 125 if (nfds < 0) … … 146 147 147 148 rtems_task_ident (RTEMS_SELF, 0, &tid); 148 rtems_event_system_receive ( SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &events);149 rtems_event_system_receive (in, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT, &out); 149 150 for (;;) { 150 151 rtems_bsdnet_semaphore_obtain (); … … 160 161 then = now; 161 162 } 162 rtems_event_system_receive ( SBWAIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, timo, &events);163 rtems_event_system_receive (in, RTEMS_EVENT_ANY | RTEMS_WAIT, timo, &out); 163 164 } 164 165 -
cpukit/libnetworking/rtems/rtems_syscall.c
r51c88e8b rf87ede5 205 205 return -1; 206 206 } 207 while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { 207 error = so->so_error; 208 while (error == 0 && (so->so_state & SS_ISCONNECTING)) { 208 209 error = soconnsleep (so); 209 210 if (error) 210 211 break; 211 }212 if (error == 0) {213 212 error = so->so_error; 214 213 so->so_error = 0; 215 214 } 216 215 bad: 217 so->so_state &= ~SS_ISCONNECTING; 216 if (error != ENXIO) 217 so->so_state &= ~SS_ISCONNECTING; 218 218 m_freem (nam); 219 219 if (error) … … 250 250 struct socket *head, *so; 251 251 struct mbuf *nam; 252 int error; 252 253 253 254 rtems_bsdnet_semaphore_obtain (); … … 266 267 return -1; 267 268 } 268 while (head->so_comp.tqh_first == NULL && head->so_error == 0) { 269 error = head->so_error; 270 while (error == 0 && head->so_comp.tqh_first == NULL) { 269 271 if (head->so_state & SS_CANTRCVMORE) { 270 head->so_error = ECONNABORTED;272 error = ECONNABORTED; 271 273 break; 272 274 } 273 head->so_error = soconnsleep (head);275 error = soconnsleep (head); 274 276 } 275 if (head->so_error) { 276 errno = head->so_error; 277 head->so_error = 0; 277 if (error) { 278 errno = error; 278 279 rtems_bsdnet_semaphore_release (); 279 280 return -1; … … 716 717 return -1; 717 718 } 719 iop->data1 = NULL; 718 720 error = soclose (so); 719 721 rtems_bsdnet_semaphore_release (); -
cpukit/rtems/include/rtems/rtems/event.h
r51c88e8b rf87ede5 315 315 316 316 /** 317 * @brief Reserved system event for network socket close. 318 */ 319 #define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26 320 321 /** 317 322 * @brief Reserved system event for transient usage. 318 323 */ -
testsuites/libtests/syscall01/init.c
r51c88e8b rf87ede5 1 1 /* 2 * Copyright (c) 2012 embedded brains GmbH. All rights reserved.2 * Copyright (c) 2012-2015 embedded brains GmbH. All rights reserved. 3 3 * 4 4 * embedded brains GmbH 5 * Obere Lagerstr. 305 * Dornierstr. 4 6 6 * 82178 Puchheim 7 7 * Germany … … 19 19 #include "tmacros.h" 20 20 21 #include <sys/select.h> 21 22 #include <sys/socket.h> 22 23 #include <sys/stat.h> 24 #include <netinet/in.h> 23 25 #include <errno.h> 24 26 #include <fcntl.h> … … 30 32 const char rtems_test_name[] = "SYSCALL 1"; 31 33 32 /* forward declarations to avoid warnings */33 static rtems_task Init(rtems_task_argument argument);34 35 34 static const char open_driver_path [] = "/dev/open_driver"; 36 35 37 36 struct rtems_bsdnet_config rtems_bsdnet_config; 38 37 39 static void test(void) 38 typedef struct { 39 rtems_id main_task; 40 rtems_id close_task; 41 int fd; 42 } test_context; 43 44 static test_context test_instance; 45 46 static void test_sync(void) 40 47 { 41 48 int rv; … … 77 84 } 78 85 86 static void close_task(rtems_task_argument arg) 87 { 88 test_context *ctx = (test_context *) arg; 89 90 while (true) { 91 rtems_status_code sc; 92 int rv; 93 94 rv = close(ctx->fd); 95 rtems_test_assert(rv == 0); 96 97 sc = rtems_event_transient_send(ctx->main_task); 98 rtems_test_assert(sc == RTEMS_SUCCESSFUL); 99 } 100 } 101 102 static void wait_for_close_task(void) 103 { 104 rtems_status_code sc; 105 106 sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); 107 rtems_test_assert(sc == RTEMS_SUCCESSFUL); 108 } 109 110 static void test_accept_and_close(test_context *ctx) 111 { 112 int rv; 113 int fd; 114 struct sockaddr_in addr; 115 socklen_t addrlen = sizeof(addr); 116 117 ctx->fd = socket(PF_INET, SOCK_STREAM, 0); 118 rtems_test_assert(ctx->fd >= 0); 119 120 rv = listen(ctx->fd, 1); 121 rtems_test_assert(rv == 0); 122 123 errno = 0; 124 fd = accept(ctx->fd, (struct sockaddr *) &addr, &addrlen); 125 rtems_test_assert(fd == -1); 126 rtems_test_assert(errno == ENXIO); 127 128 errno = 0; 129 fd = accept(ctx->fd, (struct sockaddr *) &addr, &addrlen); 130 rtems_test_assert(fd == -1); 131 rtems_test_assert(errno == EBADF); 132 133 wait_for_close_task(); 134 } 135 136 static void test_connect_and_close(test_context *ctx) 137 { 138 int rv; 139 struct sockaddr_in addr; 140 socklen_t addrlen = sizeof(addr); 141 142 ctx->fd = socket(PF_INET, SOCK_STREAM, 0); 143 rtems_test_assert(ctx->fd >= 0); 144 145 memset(&addr, 0, sizeof(addr)); 146 addr.sin_family = AF_INET; 147 addr.sin_port = htons(1234); 148 addr.sin_addr.s_addr = htonl(INADDR_ANY); 149 150 errno = 0; 151 rv = connect(ctx->fd, (struct sockaddr *) &addr, addrlen); 152 rtems_test_assert(rv == -1); 153 rtems_test_assert(errno == ENXIO); 154 155 errno = 0; 156 rv = connect(ctx->fd, (struct sockaddr *) &addr, addrlen); 157 rtems_test_assert(rv == -1); 158 rtems_test_assert(errno == EBADF); 159 160 wait_for_close_task(); 161 } 162 163 static void test_recv_and_close(test_context *ctx) 164 { 165 int rv; 166 struct sockaddr_in addr; 167 socklen_t addrlen = sizeof(addr); 168 char buf[1]; 169 ssize_t n; 170 171 ctx->fd = socket(PF_INET, SOCK_DGRAM, 0); 172 rtems_test_assert(ctx->fd >= 0); 173 174 memset(&addr, 0, sizeof(addr)); 175 addr.sin_family = AF_INET; 176 addr.sin_port = htons(1234); 177 addr.sin_addr.s_addr = htonl(INADDR_ANY); 178 179 rv = bind(ctx->fd, (struct sockaddr *) &addr, addrlen); 180 rtems_test_assert(rv == 0); 181 182 errno = 0; 183 n = recv(ctx->fd, &buf[0], sizeof(buf), 0); 184 rtems_test_assert(n == -1); 185 rtems_test_assert(errno == ENXIO); 186 187 errno = 0; 188 n = recv(ctx->fd, &buf[0], sizeof(buf), 0); 189 rtems_test_assert(n == -1); 190 rtems_test_assert(errno == EBADF); 191 192 wait_for_close_task(); 193 } 194 195 static void test_select_and_close(test_context *ctx) 196 { 197 int rv; 198 struct sockaddr_in addr; 199 socklen_t addrlen = sizeof(addr); 200 int nfds; 201 struct fd_set set; 202 203 ctx->fd = socket(PF_INET, SOCK_DGRAM, 0); 204 rtems_test_assert(ctx->fd >= 0); 205 206 memset(&addr, 0, sizeof(addr)); 207 addr.sin_family = AF_INET; 208 addr.sin_port = htons(1234); 209 addr.sin_addr.s_addr = htonl(INADDR_ANY); 210 211 rv = bind(ctx->fd, (struct sockaddr *) &addr, addrlen); 212 rtems_test_assert(rv == 0); 213 214 nfds = ctx->fd + 1; 215 FD_ZERO(&set); 216 FD_SET(ctx->fd, &set); 217 218 errno = 0; 219 rv = select(nfds, &set, NULL, NULL, NULL); 220 rtems_test_assert(rv == -1); 221 rtems_test_assert(errno == EBADF); 222 223 wait_for_close_task(); 224 } 225 79 226 static void Init(rtems_task_argument arg) 80 227 { 228 test_context *ctx = &test_instance; 229 rtems_status_code sc; 81 230 int rv; 82 231 83 232 TEST_BEGIN(); 84 233 234 ctx->main_task = rtems_task_self(); 235 236 sc = rtems_task_create( 237 rtems_build_name('C', 'L', 'O', 'S'), 238 2, 239 RTEMS_MINIMUM_STACK_SIZE, 240 RTEMS_DEFAULT_MODES, 241 RTEMS_DEFAULT_ATTRIBUTES, 242 &ctx->close_task 243 ); 244 rtems_test_assert(sc == RTEMS_SUCCESSFUL); 245 246 sc = rtems_task_start( 247 ctx->close_task, 248 close_task, 249 (rtems_task_argument) ctx 250 ); 251 rtems_test_assert(sc == RTEMS_SUCCESSFUL); 252 85 253 rv = rtems_bsdnet_initialize_network(); 86 254 rtems_test_assert(rv == 0); 87 255 88 test(); 256 test_sync(); 257 test_accept_and_close(ctx); 258 test_connect_and_close(ctx); 259 test_recv_and_close(ctx); 260 test_select_and_close(ctx); 261 262 sc = rtems_task_delete(ctx->close_task); 263 rtems_test_assert(sc == RTEMS_SUCCESSFUL); 89 264 90 265 TEST_END(); … … 130 305 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4 131 306 132 #define CONFIGURE_MAXIMUM_TASKS 2307 #define CONFIGURE_MAXIMUM_TASKS 3 133 308 134 309 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION -
testsuites/samples/loopback/init.c
r51c88e8b rf87ede5 168 168 s1 = accept(s, (struct sockaddr *)&farAddr, &addrlen); 169 169 if (s1 < 0) 170 rtems_panic("Can't accept connection: %s", strerror(errno)); 170 if (errno == ENXIO) 171 rtems_task_delete(RTEMS_SELF); 172 else 173 rtems_panic("Can't accept connection: %s", strerror(errno)); 171 174 else 172 175 printf("ACCEPTED:%lX\n", ntohl(farAddr.sin_addr.s_addr));
Note: See TracChangeset
for help on using the changeset viewer.