⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network.c

📁 业界著名的tomcat服务器的最新6.0的源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 *
 * @author Mladen Turk
 * @version $Revision: 487786 $, $Date: 2006-12-16 12:05:57 +0100 (sam., 16 déc. 2006) $
 */

#include "tcn.h"

#ifdef TCN_DO_STATISTICS

#include "apr_atomic.h"

static volatile apr_uint32_t sp_created  = 0;
static volatile apr_uint32_t sp_closed   = 0;
static volatile apr_uint32_t sp_cleared  = 0;
static volatile apr_uint32_t sp_accepted = 0;
static volatile apr_uint32_t sp_max_send = 0;
static volatile apr_uint32_t sp_min_send = 10000000;
static volatile apr_uint32_t sp_num_send = 0;
static volatile apr_off_t    sp_tot_send = 0;
static volatile apr_uint32_t sp_max_recv = 0;
static volatile apr_uint32_t sp_min_recv = 10000000;
static volatile apr_uint32_t sp_num_recv = 0;
static volatile apr_off_t    sp_tot_recv = 0;
static volatile apr_uint32_t sp_err_recv = 0;
static volatile apr_uint32_t sp_tmo_recv = 0;
static volatile apr_uint32_t sp_rst_recv = 0;
static volatile apr_status_t sp_erl_recv = 0;

static volatile apr_size_t   sf_max_send = 0;
static volatile apr_size_t   sf_min_send = 10000000;
static volatile apr_uint32_t sf_num_send = 0;
static volatile apr_off_t    sf_tot_send = 0;

void sp_network_dump_statistics()
{
    fprintf(stderr, "Network Statistics ......\n");
    fprintf(stderr, "Sockets created         : %d\n", sp_created);
    fprintf(stderr, "Sockets accepted        : %d\n", sp_accepted);
    fprintf(stderr, "Sockets closed          : %d\n", sp_closed);
    fprintf(stderr, "Sockets cleared         : %d\n", sp_cleared);
    fprintf(stderr, "Total send calls        : %d\n", sp_num_send);
    fprintf(stderr, "Minimum send length     : %d\n", sp_min_send);
    fprintf(stderr, "Maximum send length     : %d\n", sp_max_send);
    fprintf(stderr, "Average send length     : %.2f\n", (double)sp_tot_send/(double)sp_num_send);
    fprintf(stderr, "Total recv calls        : %d\n", sp_num_recv);
    fprintf(stderr, "Minimum recv length     : %d\n", sp_min_recv);
    fprintf(stderr, "Maximum recv length     : %d\n", sp_max_recv);
    fprintf(stderr, "Average recv length     : %.2f\n", (double)sp_tot_recv/(double)sp_num_recv);
    fprintf(stderr, "Receive timeouts        : %d\n", sp_tmo_recv);
    fprintf(stderr, "Receive errors          : %d\n", sp_err_recv);
    fprintf(stderr, "Receive resets          : %d\n", sp_rst_recv);
    fprintf(stderr, "Last receive error      : %d\n", sp_erl_recv);

    fprintf(stderr, "Total sendfile calls    : %d\n", sf_num_send);
    fprintf(stderr, "Minimum sendfile lenght : %" APR_SIZE_T_FMT "\n", sf_min_send);
    fprintf(stderr, "Maximum sendfile lenght : %" APR_SIZE_T_FMT "\n", sf_max_send);

}

#endif /* TCN_DO_STATISTICS */

static apr_status_t sp_socket_cleanup(void *data)
{
    tcn_socket_t *s = (tcn_socket_t *)data;

    if (s->net && s->net->cleanup)
        (*s->net->cleanup)(s->opaque);
    if (s->sock) {
        apr_socket_t *as = s->sock;
        s->sock = NULL;
        apr_socket_close(as);
    }
#ifdef TCN_DO_STATISTICS
    apr_atomic_inc32(&sp_cleared);
#endif
    return APR_SUCCESS;
}

#if defined(DEBUG) || defined(_DEBUG)
static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_send(apr_socket_t *sock, const char *buf, apr_size_t *len)
{
    return apr_socket_send(sock, buf, len);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_recv(apr_socket_t *sock, char *buf, apr_size_t *len)
{
    return apr_socket_recv(sock, buf, len);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_sendv(apr_socket_t *sock, const struct iovec *vec,
                 apr_int32_t nvec, apr_size_t *len)
{
    return apr_socket_sendv(sock, vec, nvec, len);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_shutdown(apr_socket_t *sock, apr_shutdown_how_e how)
{
    return apr_socket_shutdown(sock, how);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
{
    return apr_socket_timeout_set(sock, t);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_timeout_get(apr_socket_t *sock, apr_interval_time_t *t)
{
    return apr_socket_timeout_get(sock, t);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_opt_set(apr_socket_t *sock, apr_int32_t opt, apr_int32_t on)
{
    return apr_socket_opt_set(sock, opt, on);
}

static APR_INLINE apr_status_t APR_THREAD_FUNC
APR_socket_opt_get(apr_socket_t *sock, apr_int32_t opt, apr_int32_t *on)
{
    return apr_socket_opt_get(sock, opt, on);
}

#else
#define APR_socket_send         apr_socket_send
#define APR_socket_recv         apr_socket_recv
#define APR_socket_sendv        apr_socket_sendv
#define APR_socket_shutdown     apr_socket_shutdown
#define APR_socket_timeout_set  apr_socket_timeout_set
#define APR_socket_timeout_get  apr_socket_timeout_get
#define APR_socket_opt_set      apr_socket_opt_set
#define APR_socket_opt_get      apr_socket_opt_get
#endif

static tcn_nlayer_t apr_socket_layer = {
    TCN_SOCKET_APR,
    NULL,
    NULL,
    APR_socket_shutdown,
    APR_socket_opt_get,
    APR_socket_opt_set,
    APR_socket_timeout_get,
    APR_socket_timeout_set,
    APR_socket_send,
    APR_socket_sendv,
    APR_socket_recv
};

TCN_IMPLEMENT_CALL(jlong, Socket, create)(TCN_STDARGS, jint family,
                                          jint type, jint protocol,
                                          jlong pool)
{
    apr_pool_t *p = J2P(pool, apr_pool_t *);
    apr_socket_t *s = NULL;
    tcn_socket_t *a = NULL;
    apr_int32_t f, t;

    UNREFERENCED(o);
    TCN_ASSERT(pool != 0);
    GET_S_FAMILY(f, family);
    GET_S_TYPE(t, type);

    a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
    TCN_CHECK_ALLOCATED(a);
    a->pool = p;
    if (family >= 0)
        a->net = &apr_socket_layer;
    apr_pool_cleanup_register(p, (const void *)a,
                              sp_socket_cleanup,
                              apr_pool_cleanup_null);

    if (family >= 0) {
        TCN_THROW_IF_ERR(apr_socket_create(&s,
                         f, t, protocol, p), a);
    }
#ifdef TCN_DO_STATISTICS
    sp_created++;
#endif
    a->sock = s;
    if (family >= 0)
        a->net = &apr_socket_layer;
    a->opaque   = s;
    apr_pool_create(&a->child, a->pool);

    return P2J(a);
cleanup:
    return 0;

}

TCN_IMPLEMENT_CALL(void, Socket, destroy)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);

    apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
    if (s->net && s->net->cleanup) {
        (*s->net->cleanup)(s->opaque);
        s->net = NULL;
    }
    if (s->sock) {
        apr_socket_t *as = s->sock;
        s->sock = NULL;
        apr_socket_close(as);
    }

    apr_pool_destroy(s->pool);
}

TCN_IMPLEMENT_CALL(jlong, Socket, pool)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_pool_t *n;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);
    TCN_THROW_IF_ERR(apr_pool_create(&n, s->pool), n);
cleanup:
    return P2J(n);
}

TCN_IMPLEMENT_CALL(jlong, Socket, get)(TCN_STDARGS, jlong sock, jint what)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);

    switch (what) {
        case TCN_SOCKET_GET_POOL:
            return P2J(s->pool);
        break;
        case TCN_SOCKET_GET_IMPL:
            return P2J(s->opaque);
        break;
        case TCN_SOCKET_GET_APRS:
            return P2J(s->sock);
        break;
        case TCN_SOCKET_GET_TYPE:
            return (jlong)(s->net->type);
        break;
    }
    return 0;
}

TCN_IMPLEMENT_CALL(jint, Socket, shutdown)(TCN_STDARGS, jlong sock,
                                           jint how)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    return (jint)(*s->net->shutdown)(s->opaque, how);
}

TCN_IMPLEMENT_CALL(jint, Socket, close)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    jint rv = APR_SUCCESS;
    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);

    apr_pool_cleanup_kill(s->pool, s, sp_socket_cleanup);
    if (s->child) {
        apr_pool_clear(s->child);
    }
#ifdef TCN_DO_STATISTICS
    apr_atomic_inc32(&sp_closed);
#endif
    if (s->net && s->net->close) {
        rv = (*s->net->close)(s->opaque);
        s->net = NULL;
    }
    if (s->sock) {
        apr_socket_t *as = s->sock;
        s->sock = NULL;
        rv = (jint)apr_socket_close(as);
    }
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Socket, bind)(TCN_STDARGS, jlong sock,
                                       jlong sa)
{
    jint rv = APR_SUCCESS;
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *a = J2P(sa, apr_sockaddr_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);
    rv = (jint)apr_socket_bind(s->sock, a);
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Socket, listen)(TCN_STDARGS, jlong sock,
                                         jint backlog)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);
    return (jint)apr_socket_listen(s->sock, backlog);
}

TCN_IMPLEMENT_CALL(jlong, Socket, acceptx)(TCN_STDARGS, jlong sock,
                                           jlong pool)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_pool_t   *p = J2P(pool, apr_pool_t *);
    apr_socket_t *n = NULL;
    tcn_socket_t *a = NULL;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    if (s->net->type == TCN_SOCKET_APR) {
        TCN_ASSERT(s->sock != NULL);
        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
        TCN_CHECK_ALLOCATED(a);
        a->pool   = p;
        apr_pool_cleanup_register(p, (const void *)a,
                                  sp_socket_cleanup,
                                  apr_pool_cleanup_null);

        TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
    }
    else {
        tcn_ThrowAPRException(e, APR_ENOTIMPL);
        goto cleanup;
    }
    if (n) {
#ifdef TCN_DO_STATISTICS
        apr_atomic_inc32(&sp_accepted);
#endif
        a->net    = &apr_socket_layer;
        a->sock   = n;
        a->opaque = n;
    }

cleanup:
    return P2J(a);
}

TCN_IMPLEMENT_CALL(jlong, Socket, accept)(TCN_STDARGS, jlong sock)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_pool_t   *p = NULL;
    apr_socket_t *n = NULL;
    tcn_socket_t *a = NULL;

    UNREFERENCED(o);
    TCN_ASSERT(sock != 0);

    TCN_THROW_IF_ERR(apr_pool_create(&p, s->pool), p);
    if (s->net->type == TCN_SOCKET_APR) {
        TCN_ASSERT(s->sock != NULL);
        a = (tcn_socket_t *)apr_pcalloc(p, sizeof(tcn_socket_t));
        TCN_CHECK_ALLOCATED(a);
        a->pool   = p;
        apr_pool_cleanup_register(s->child, (const void *)a,
                                  sp_socket_cleanup,
                                  apr_pool_cleanup_null);

        TCN_THROW_IF_ERR(apr_socket_accept(&n, s->sock, p), n);
    }
    else {
        tcn_ThrowAPRException(e, APR_ENOTIMPL);
        goto cleanup;
    }
    if (n) {
#ifdef TCN_DO_STATISTICS
        apr_atomic_inc32(&sp_accepted);
#endif
        a->net    = &apr_socket_layer;
        a->sock   = n;
        a->opaque = n;
    }
    return P2J(a);
cleanup:
    return 0;
}

TCN_IMPLEMENT_CALL(jint, Socket, connect)(TCN_STDARGS, jlong sock,
                                          jlong sa)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_sockaddr_t *a = J2P(sa, apr_sockaddr_t *);

    UNREFERENCED_STDARGS;
    TCN_ASSERT(sock != 0);
    TCN_ASSERT(s->sock != NULL);
    return (jint)apr_socket_connect(s->sock, a);
}

TCN_IMPLEMENT_CALL(jint, Socket, send)(TCN_STDARGS, jlong sock,
                                      jbyteArray buf, jint offset, jint tosend)
{
    tcn_socket_t *s = J2P(sock, tcn_socket_t *);
    apr_size_t nbytes = (apr_size_t)tosend;
    apr_status_t ss;

    UNREFERENCED(o);
    if (!sock) {
        tcn_ThrowAPRException(e, APR_ENOTSOCK);
        return -(jint)APR_ENOTSOCK;
    }
    TCN_ASSERT(s->opaque != NULL);
#ifdef TCN_DO_STATISTICS
    sp_max_send = TCN_MAX(sp_max_send, nbytes);
    sp_min_send = TCN_MIN(sp_min_send, nbytes);
    sp_tot_send += nbytes;
    sp_num_send++;
#endif

    if (tosend <= TCN_BUFFER_SZ) {
        jbyte sb[TCN_BUFFER_SZ];
        (*e)->GetByteArrayRegion(e, buf, offset, tosend, &sb[0]);
        ss = (*s->net->send)(s->opaque, (const char *)&sb[0], &nbytes);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -