Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/svnserve/svnserve.c view on Meta::CPAN
{
svn_cache_config_t settings = *svn_cache_config_get();
if (params.memory_cache_size != -1)
settings.cache_size = params.memory_cache_size;
settings.single_threaded = TRUE;
if (handling_mode == connection_mode_thread)
{
#if APR_HAS_THREADS
settings.single_threaded = FALSE;
#else
/* No requests will be processed at all
* (see "switch (handling_mode)" code further down).
* But if they were, some other synchronization code
* would need to take care of securing integrity of
* APR-based structures. That would include our caches.
*/
#endif
}
svn_cache_config_set(&settings);
}
while (1)
{
#ifdef WIN32
if (winservice_is_stopping())
return ERROR_SUCCESS;
#endif
/* Non-standard pool handling. The main thread never blocks to join
the connection threads so it cannot clean up after each one. So
separate pools that can be cleared at thread exit are used. */
connection_pool
= apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
status = apr_socket_accept(&usock, sock, connection_pool);
if (handling_mode == connection_mode_fork)
{
/* Collect any zombie child processes. */
while (apr_proc_wait_all_procs(&proc, NULL, NULL, APR_NOWAIT,
connection_pool) == APR_CHILD_DONE)
;
}
if (APR_STATUS_IS_EINTR(status)
|| APR_STATUS_IS_ECONNABORTED(status)
|| APR_STATUS_IS_ECONNRESET(status))
{
svn_pool_destroy(connection_pool);
continue;
}
if (status)
{
err = svn_error_wrap_apr
(status, _("Can't accept client connection"));
return svn_cmdline_handle_exit_error(err, pool, "svnserve: ");
}
/* Enable TCP keep-alives on the socket so we time out when
* the connection breaks due to network-layer problems.
* If the peer has dropped the connection due to a network partition
* or a crash, or if the peer no longer considers the connection
* valid because we are behind a NAT and our public IP has changed,
* it will respond to the keep-alive probe with a RST instead of an
* acknowledgment segment, which will cause svn to abort the session
* even while it is currently blocked waiting for data from the peer. */
status = apr_socket_opt_set(usock, APR_SO_KEEPALIVE, 1);
if (status)
{
/* It's not a fatal error if we cannot enable keep-alives. */
}
conn = svn_ra_svn_create_conn3(usock, NULL, NULL,
params.compression_level,
params.zero_copy_limit,
params.error_check_interval,
connection_pool);
if (run_mode == run_mode_listen_once)
{
err = serve(conn, ¶ms, connection_pool);
if (err)
svn_handle_error2(err, stdout, FALSE, "svnserve: ");
svn_error_clear(err);
apr_socket_close(usock);
apr_socket_close(sock);
exit(0);
}
switch (handling_mode)
{
case connection_mode_fork:
#if APR_HAS_FORK
status = apr_proc_fork(&proc, connection_pool);
if (status == APR_INCHILD)
{
apr_socket_close(sock);
err = serve(conn, ¶ms, connection_pool);
log_error(err, params.log_file,
svn_ra_svn_conn_remote_host(conn),
NULL, NULL, /* user, repos */
connection_pool);
svn_error_clear(err);
apr_socket_close(usock);
exit(0);
}
else if (status == APR_INPARENT)
{
apr_socket_close(usock);
}
else
{
err = svn_error_wrap_apr(status, "apr_proc_fork");
log_error(err, params.log_file,
svn_ra_svn_conn_remote_host(conn),
NULL, NULL, /* user, repos */
connection_pool);
svn_error_clear(err);
apr_socket_close(usock);
}
svn_pool_destroy(connection_pool);
#endif
break;
case connection_mode_thread:
/* Create a detached thread for each connection. That's not a
particularly sophisticated strategy for a threaded server, it's
little different from forking one process per connection. */
( run in 0.574 second using v1.01-cache-2.11-cpan-df04353d9ac )