diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index 7a8aa4ac..d813ca1b 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -415,7 +415,7 @@ recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i) | |||
415 | (GNUTLS_E_INTERRUPTED == res) ) | 415 | (GNUTLS_E_INTERRUPTED == res) ) |
416 | { | 416 | { |
417 | MHD_socket_set_error_ (MHD_SCKT_EINTR_); | 417 | MHD_socket_set_error_ (MHD_SCKT_EINTR_); |
418 | #if EPOLL_SUPPORT | 418 | #ifdef EPOLL_SUPPORT |
419 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; | 419 | connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY; |
420 | #endif | 420 | #endif |
421 | return -1; | 421 | return -1; |
@@ -456,7 +456,7 @@ send_tls_adapter (struct MHD_Connection *connection, | |||
456 | (GNUTLS_E_INTERRUPTED == res) ) | 456 | (GNUTLS_E_INTERRUPTED == res) ) |
457 | { | 457 | { |
458 | MHD_socket_set_error_ (MHD_SCKT_EINTR_); | 458 | MHD_socket_set_error_ (MHD_SCKT_EINTR_); |
459 | #if EPOLL_SUPPORT | 459 | #ifdef EPOLL_SUPPORT |
460 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; | 460 | connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY; |
461 | #endif | 461 | #endif |
462 | return -1; | 462 | return -1; |
@@ -663,7 +663,7 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
663 | || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 663 | || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
664 | || (0 != (daemon->options & MHD_USE_POLL))) | 664 | || (0 != (daemon->options & MHD_USE_POLL))) |
665 | return MHD_NO; | 665 | return MHD_NO; |
666 | #if EPOLL_SUPPORT | 666 | #ifdef EPOLL_SUPPORT |
667 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 667 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
668 | { | 668 | { |
669 | /* we're in epoll mode, use the epoll FD as a stand-in for | 669 | /* we're in epoll mode, use the epoll FD as a stand-in for |
@@ -1047,7 +1047,7 @@ recv_param_adapter (struct MHD_Connection *connection, | |||
1047 | other, | 1047 | other, |
1048 | (MHD_SCKT_SEND_SIZE_) i, | 1048 | (MHD_SCKT_SEND_SIZE_) i, |
1049 | MSG_NOSIGNAL); | 1049 | MSG_NOSIGNAL); |
1050 | #if EPOLL_SUPPORT | 1050 | #ifdef EPOLL_SUPPORT |
1051 | if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())) ) | 1051 | if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())) ) |
1052 | { | 1052 | { |
1053 | /* Got EAGAIN --- no longer read-ready */ | 1053 | /* Got EAGAIN --- no longer read-ready */ |
@@ -1128,7 +1128,7 @@ send_param_adapter (struct MHD_Connection *connection, | |||
1128 | return ret; | 1128 | return ret; |
1129 | } | 1129 | } |
1130 | err = MHD_socket_get_error_(); | 1130 | err = MHD_socket_get_error_(); |
1131 | #if EPOLL_SUPPORT | 1131 | #ifdef EPOLL_SUPPORT |
1132 | if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) ) | 1132 | if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) ) |
1133 | { | 1133 | { |
1134 | /* EAGAIN --- no longer write-ready */ | 1134 | /* EAGAIN --- no longer write-ready */ |
@@ -1148,7 +1148,7 @@ send_param_adapter (struct MHD_Connection *connection, | |||
1148 | #endif | 1148 | #endif |
1149 | ret = (ssize_t) send (connection->socket_fd, other, (MHD_SCKT_SEND_SIZE_)i, MSG_NOSIGNAL); | 1149 | ret = (ssize_t) send (connection->socket_fd, other, (MHD_SCKT_SEND_SIZE_)i, MSG_NOSIGNAL); |
1150 | err = MHD_socket_get_error_(); | 1150 | err = MHD_socket_get_error_(); |
1151 | #if EPOLL_SUPPORT | 1151 | #ifdef EPOLL_SUPPORT |
1152 | if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) ) | 1152 | if ( (0 > ret) && (MHD_SCKT_ERR_IS_EAGAIN_(err)) ) |
1153 | { | 1153 | { |
1154 | /* EAGAIN --- no longer write-ready */ | 1154 | /* EAGAIN --- no longer write-ready */ |
@@ -1485,7 +1485,7 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
1485 | "failed to signal new connection via pipe"); | 1485 | "failed to signal new connection via pipe"); |
1486 | #endif | 1486 | #endif |
1487 | } | 1487 | } |
1488 | #if EPOLL_SUPPORT | 1488 | #ifdef EPOLL_SUPPORT |
1489 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 1489 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
1490 | { | 1490 | { |
1491 | if (0 == (daemon->options & MHD_USE_EPOLL_TURBO)) | 1491 | if (0 == (daemon->options & MHD_USE_EPOLL_TURBO)) |
@@ -1610,7 +1610,7 @@ MHD_suspend_connection (struct MHD_Connection *connection) | |||
1610 | DLL_insert (daemon->suspended_connections_head, | 1610 | DLL_insert (daemon->suspended_connections_head, |
1611 | daemon->suspended_connections_tail, | 1611 | daemon->suspended_connections_tail, |
1612 | connection); | 1612 | connection); |
1613 | #if EPOLL_SUPPORT | 1613 | #ifdef EPOLL_SUPPORT |
1614 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 1614 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
1615 | { | 1615 | { |
1616 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 1616 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
@@ -1728,7 +1728,7 @@ resume_suspended_connections (struct MHD_Daemon *daemon) | |||
1728 | daemon->manual_timeout_tail, | 1728 | daemon->manual_timeout_tail, |
1729 | pos); | 1729 | pos); |
1730 | } | 1730 | } |
1731 | #if EPOLL_SUPPORT | 1731 | #ifdef EPOLL_SUPPORT |
1732 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 1732 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
1733 | { | 1733 | { |
1734 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 1734 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
@@ -1970,7 +1970,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
1970 | &pos->socket_context, | 1970 | &pos->socket_context, |
1971 | MHD_CONNECTION_NOTIFY_CLOSED); | 1971 | MHD_CONNECTION_NOTIFY_CLOSED); |
1972 | MHD_ip_limit_del (daemon, pos->addr, pos->addr_len); | 1972 | MHD_ip_limit_del (daemon, pos->addr, pos->addr_len); |
1973 | #if EPOLL_SUPPORT | 1973 | #ifdef EPOLL_SUPPORT |
1974 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 1974 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
1975 | { | 1975 | { |
1976 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 1976 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
@@ -2152,7 +2152,7 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
2152 | if (MHD_USE_SUSPEND_RESUME == (daemon->options & mask)) | 2152 | if (MHD_USE_SUSPEND_RESUME == (daemon->options & mask)) |
2153 | resume_suspended_connections (daemon); | 2153 | resume_suspended_connections (daemon); |
2154 | 2154 | ||
2155 | #if EPOLL_SUPPORT | 2155 | #ifdef EPOLL_SUPPORT |
2156 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 2156 | if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
2157 | { | 2157 | { |
2158 | /* we're in epoll mode, the epoll FD stands for | 2158 | /* we're in epoll mode, the epoll FD stands for |
@@ -2583,7 +2583,7 @@ MHD_poll (struct MHD_Daemon *daemon, | |||
2583 | } | 2583 | } |
2584 | 2584 | ||
2585 | 2585 | ||
2586 | #if EPOLL_SUPPORT | 2586 | #ifdef EPOLL_SUPPORT |
2587 | 2587 | ||
2588 | /** | 2588 | /** |
2589 | * How many events to we process at most per epoll() call? Trade-off | 2589 | * How many events to we process at most per epoll() call? Trade-off |
@@ -2833,7 +2833,7 @@ MHD_run (struct MHD_Daemon *daemon) | |||
2833 | MHD_poll (daemon, MHD_NO); | 2833 | MHD_poll (daemon, MHD_NO); |
2834 | MHD_cleanup_connections (daemon); | 2834 | MHD_cleanup_connections (daemon); |
2835 | } | 2835 | } |
2836 | #if EPOLL_SUPPORT | 2836 | #ifdef EPOLL_SUPPORT |
2837 | else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 2837 | else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
2838 | { | 2838 | { |
2839 | MHD_epoll (daemon, MHD_NO); | 2839 | MHD_epoll (daemon, MHD_NO); |
@@ -2865,7 +2865,7 @@ MHD_select_thread (void *cls) | |||
2865 | { | 2865 | { |
2866 | if (0 != (daemon->options & MHD_USE_POLL)) | 2866 | if (0 != (daemon->options & MHD_USE_POLL)) |
2867 | MHD_poll (daemon, MHD_YES); | 2867 | MHD_poll (daemon, MHD_YES); |
2868 | #if EPOLL_SUPPORT | 2868 | #ifdef EPOLL_SUPPORT |
2869 | else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) | 2869 | else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) |
2870 | MHD_epoll (daemon, MHD_YES); | 2870 | MHD_epoll (daemon, MHD_YES); |
2871 | #endif | 2871 | #endif |
@@ -2972,7 +2972,7 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon) | |||
2972 | for (i = 0; i < daemon->worker_pool_size; i++) | 2972 | for (i = 0; i < daemon->worker_pool_size; i++) |
2973 | { | 2973 | { |
2974 | daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET; | 2974 | daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET; |
2975 | #if EPOLL_SUPPORT | 2975 | #ifdef EPOLL_SUPPORT |
2976 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && | 2976 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && |
2977 | (-1 != daemon->worker_pool[i].epoll_fd) && | 2977 | (-1 != daemon->worker_pool[i].epoll_fd) && |
2978 | (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) ) | 2978 | (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) ) |
@@ -2993,7 +2993,7 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon) | |||
2993 | } | 2993 | } |
2994 | } | 2994 | } |
2995 | daemon->socket_fd = MHD_INVALID_SOCKET; | 2995 | daemon->socket_fd = MHD_INVALID_SOCKET; |
2996 | #if EPOLL_SUPPORT | 2996 | #ifdef EPOLL_SUPPORT |
2997 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && | 2997 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && |
2998 | (-1 != daemon->epoll_fd) && | 2998 | (-1 != daemon->epoll_fd) && |
2999 | (MHD_YES == daemon->listen_socket_in_epoll) ) | 2999 | (MHD_YES == daemon->listen_socket_in_epoll) ) |
@@ -3414,7 +3414,7 @@ parse_options_va (struct MHD_Daemon *daemon, | |||
3414 | } | 3414 | } |
3415 | 3415 | ||
3416 | 3416 | ||
3417 | #if EPOLL_SUPPORT | 3417 | #ifdef EPOLL_SUPPORT |
3418 | /** | 3418 | /** |
3419 | * Setup epoll() FD for the daemon and initialize it to listen | 3419 | * Setup epoll() FD for the daemon and initialize it to listen |
3420 | * on the listen FD. | 3420 | * on the listen FD. |
@@ -3549,7 +3549,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
3549 | if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) | 3549 | if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) |
3550 | return NULL; | 3550 | return NULL; |
3551 | memset (daemon, 0, sizeof (struct MHD_Daemon)); | 3551 | memset (daemon, 0, sizeof (struct MHD_Daemon)); |
3552 | #if EPOLL_SUPPORT | 3552 | #ifdef EPOLL_SUPPORT |
3553 | daemon->epoll_fd = -1; | 3553 | daemon->epoll_fd = -1; |
3554 | #endif | 3554 | #endif |
3555 | /* try to open listen socket */ | 3555 | /* try to open listen socket */ |
@@ -3999,7 +3999,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
3999 | goto free_and_fail; | 3999 | goto free_and_fail; |
4000 | } | 4000 | } |
4001 | 4001 | ||
4002 | #if EPOLL_SUPPORT | 4002 | #ifdef EPOLL_SUPPORT |
4003 | if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) && | 4003 | if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) && |
4004 | (0 == daemon->worker_pool_size) && | 4004 | (0 == daemon->worker_pool_size) && |
4005 | (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) ) | 4005 | (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) ) |
@@ -4172,7 +4172,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
4172 | d->connection_limit = conns_per_thread; | 4172 | d->connection_limit = conns_per_thread; |
4173 | if (i < leftover_conns) | 4173 | if (i < leftover_conns) |
4174 | ++d->connection_limit; | 4174 | ++d->connection_limit; |
4175 | #if EPOLL_SUPPORT | 4175 | #ifdef EPOLL_SUPPORT |
4176 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && | 4176 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && |
4177 | (MHD_YES != setup_epoll_to_listen (d)) ) | 4177 | (MHD_YES != setup_epoll_to_listen (d)) ) |
4178 | goto thread_failed; | 4178 | goto thread_failed; |
@@ -4242,7 +4242,7 @@ thread_failed: | |||
4242 | free_and_fail: | 4242 | free_and_fail: |
4243 | /* clean up basic memory state in 'daemon' and return NULL to | 4243 | /* clean up basic memory state in 'daemon' and return NULL to |
4244 | indicate failure */ | 4244 | indicate failure */ |
4245 | #if EPOLL_SUPPORT | 4245 | #ifdef EPOLL_SUPPORT |
4246 | if (-1 != daemon->epoll_fd) | 4246 | if (-1 != daemon->epoll_fd) |
4247 | close (daemon->epoll_fd); | 4247 | close (daemon->epoll_fd); |
4248 | #endif | 4248 | #endif |
@@ -4362,7 +4362,7 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
4362 | } | 4362 | } |
4363 | 4363 | ||
4364 | 4364 | ||
4365 | #if EPOLL_SUPPORT | 4365 | #ifdef EPOLL_SUPPORT |
4366 | /** | 4366 | /** |
4367 | * Shutdown epoll()-event loop by adding 'wpipe' to its event set. | 4367 | * Shutdown epoll()-event loop by adding 'wpipe' to its event set. |
4368 | * | 4368 | * |
@@ -4417,7 +4417,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
4417 | { | 4417 | { |
4418 | daemon->worker_pool[i].shutdown = MHD_YES; | 4418 | daemon->worker_pool[i].shutdown = MHD_YES; |
4419 | daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET; | 4419 | daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET; |
4420 | #if EPOLL_SUPPORT | 4420 | #ifdef EPOLL_SUPPORT |
4421 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && | 4421 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && |
4422 | (-1 != daemon->worker_pool[i].epoll_fd) && | 4422 | (-1 != daemon->worker_pool[i].epoll_fd) && |
4423 | (MHD_INVALID_SOCKET == fd) ) | 4423 | (MHD_INVALID_SOCKET == fd) ) |
@@ -4439,7 +4439,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
4439 | (void) shutdown (fd, SHUT_RDWR); | 4439 | (void) shutdown (fd, SHUT_RDWR); |
4440 | } | 4440 | } |
4441 | #endif | 4441 | #endif |
4442 | #if EPOLL_SUPPORT | 4442 | #ifdef EPOLL_SUPPORT |
4443 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && | 4443 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && |
4444 | (-1 != daemon->epoll_fd) && | 4444 | (-1 != daemon->epoll_fd) && |
4445 | (MHD_INVALID_SOCKET == fd) ) | 4445 | (MHD_INVALID_SOCKET == fd) ) |
@@ -4469,7 +4469,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
4469 | MHD_PANIC ("Failed to join a thread\n"); | 4469 | MHD_PANIC ("Failed to join a thread\n"); |
4470 | close_all_connections (&daemon->worker_pool[i]); | 4470 | close_all_connections (&daemon->worker_pool[i]); |
4471 | (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex); | 4471 | (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex); |
4472 | #if EPOLL_SUPPORT | 4472 | #ifdef EPOLL_SUPPORT |
4473 | if ( (-1 != daemon->worker_pool[i].epoll_fd) && | 4473 | if ( (-1 != daemon->worker_pool[i].epoll_fd) && |
4474 | (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) ) | 4474 | (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) ) |
4475 | MHD_PANIC ("close failed\n"); | 4475 | MHD_PANIC ("close failed\n"); |
@@ -4520,7 +4520,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
4520 | gnutls_certificate_free_credentials (daemon->x509_cred); | 4520 | gnutls_certificate_free_credentials (daemon->x509_cred); |
4521 | } | 4521 | } |
4522 | #endif | 4522 | #endif |
4523 | #if EPOLL_SUPPORT | 4523 | #ifdef EPOLL_SUPPORT |
4524 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && | 4524 | if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) && |
4525 | (-1 != daemon->epoll_fd) && | 4525 | (-1 != daemon->epoll_fd) && |
4526 | (0 != MHD_socket_close_ (daemon->epoll_fd)) ) | 4526 | (0 != MHD_socket_close_ (daemon->epoll_fd)) ) |
@@ -4569,7 +4569,7 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon, | |||
4569 | return NULL; /* no longer supported */ | 4569 | return NULL; /* no longer supported */ |
4570 | case MHD_DAEMON_INFO_LISTEN_FD: | 4570 | case MHD_DAEMON_INFO_LISTEN_FD: |
4571 | return (const union MHD_DaemonInfo *) &daemon->socket_fd; | 4571 | return (const union MHD_DaemonInfo *) &daemon->socket_fd; |
4572 | #if EPOLL_SUPPORT | 4572 | #ifdef EPOLL_SUPPORT |
4573 | case MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY: | 4573 | case MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY: |
4574 | return (const union MHD_DaemonInfo *) &daemon->epoll_fd; | 4574 | return (const union MHD_DaemonInfo *) &daemon->epoll_fd; |
4575 | #endif | 4575 | #endif |
@@ -4699,7 +4699,7 @@ MHD_is_feature_supported(enum MHD_FEATURE feature) | |||
4699 | return MHD_NO; | 4699 | return MHD_NO; |
4700 | #endif | 4700 | #endif |
4701 | case MHD_FEATURE_EPOLL: | 4701 | case MHD_FEATURE_EPOLL: |
4702 | #if EPOLL_SUPPORT | 4702 | #ifdef EPOLL_SUPPORT |
4703 | return MHD_YES; | 4703 | return MHD_YES; |
4704 | #else | 4704 | #else |
4705 | return MHD_NO; | 4705 | return MHD_NO; |