예제 #1
0
/**
 * Socket(Listener only): Get contact string.
 */
char *
ngrcSocketGetContactString(
    ngrcSocket_t *sock)
{
    ngLog_t *log;
    struct sockaddr_in addr; 
    char *ret = NULL;
    int result;
    ngiSockLen_t addr_len = sizeof(addr);
    NGEM_FNAME(ngrcSocketGetContactString);

    NGEM_ASSERT(sock != NULL);

    log = ngemLogGetDefault();

    /* TODO: Local socket */
    result = getsockname(sock->ngs_fd, (struct sockaddr *)&addr, &addr_len);
    if (result < 0) {
        ngLogError(log, NGRC_LOGCAT_GT, fName,
            "getsockname: %s\n", strerror(errno));
        return NULL;
    }

    NGEM_ASSERT(addr.sin_family == AF_INET);

    /* Remote Communication Proxy uses local address only. */
    ret = ngemStrdupPrintf("ng_tcp://localhost:%d/",
        ntohs(addr.sin_port));
    if (ret == NULL) {
        ngLogError(log, NGRC_LOGCAT_GT, fName,
            "Can't create address string.\n");
        return NULL;
    }
    return ret;
}
예제 #2
0
/**
 * Socket: Read
 * if nread == 0, EOF or Canceled.
 */
ngemResult_t
ngrcSocketRead(
    ngrcSocket_t *sock,
    void *buf,
    size_t size,
    size_t *nread)
{
    fd_set rfds;
    int result;
    ngLog_t *log;
    int fdmax;
    ssize_t nr = -1;
    NGEM_FNAME(ngrcSocketRead);

    NGEM_ASSERT(sock != NULL);
    NGEM_ASSERT(buf != NULL);
    NGEM_ASSERT(size > 0);
    NGEM_ASSERT(nread != NULL);

    *nread = 0;

    log = ngemLogGetDefault();

    while (nr < 0) {
        FD_ZERO(&rfds);
        FD_SET(sock->ngs_fd, &rfds);
        FD_SET(NGEM_PIPE_IN(sock->ngs_pipe), &rfds);

        fdmax = NGEM_MAX(sock->ngs_fd, NGEM_PIPE_IN(sock->ngs_pipe)) + 1;

        result = select(fdmax, &rfds, NULL, NULL, NULL);
        if (result < 0) {
            if (errno == EINTR) {
                continue;
            }
            ngLogError(log, NGRC_LOGCAT_GT, fName,
                "select: %s\n", strerror(errno));
            return NGEM_FAILED;
        }

        if (FD_ISSET(NGEM_PIPE_IN(sock->ngs_pipe), &rfds)) {
            /* Not continue */
            return NGEM_SUCCESS;
        }

        if (FD_ISSET(sock->ngs_fd, &rfds)) {
            nr = read(sock->ngs_fd, buf, size);
            if (nr < 0) {
                if (errno == EAGAIN) {continue;}
                ngLogError(log, NGRC_LOGCAT_GT, fName,
                    "read: %s\n", strerror(errno));
                return NGEM_SUCCESS;
            }
        }
    }
    *nread = nr;
    return NGEM_SUCCESS;
}
예제 #3
0
/**
 * Operator: Finalize
 */
ngemResult_t
ngrcOperatorFinalize(
    ngrcOperator_t*op)
{
    globus_result_t gResult;
    ngLog_t *log;
    ngemResult_t ret = NGEM_SUCCESS;
    NGEM_FNAME(ngrcOperatorFinalize);

    log = ngemLogGetDefault();

    NGEM_ASSERT(op != NULL);

    op->ngo_handle   = NULL;
    op->ngo_canceled = false;

    gResult = globus_mutex_destroy(&op->ngo_mutex);
    if (gResult != GLOBUS_SUCCESS) {
        ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
            "globus_mutex_destroy", gResult);
        ret = NGEM_FAILED;
    }
    gResult = globus_cond_destroy(&op->ngo_cond);
    if (gResult != GLOBUS_SUCCESS) {
        ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
            "globus_cond_destroy", gResult);
        ret = NGEM_FAILED;
    }

    return ret;
}
예제 #4
0
/**
 * Operator: Initialize
 */
ngemResult_t
ngrcOperatorInitialize(
    ngrcOperator_t *op,
    globus_xio_handle_t handle)
{
    globus_result_t gResult;
    ngLog_t *log;
    bool mutexInitialized = false;
    NGEM_FNAME(ngrcOperatorInitialize);

    log = ngemLogGetDefault();

    NGEM_ASSERT(op != NULL);
    NGEM_ASSERT(handle != NULL);

    op->ngo_handle    = handle;
    op->ngo_canceled  = false;

    gResult = globus_mutex_init(&op->ngo_mutex, NULL);
    if (gResult != GLOBUS_SUCCESS) {
        ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
            "globus_mutex_init", gResult);
        goto error;
    }
    mutexInitialized = true;

    globus_cond_init(&op->ngo_cond, NULL);
    if (gResult != GLOBUS_SUCCESS) {
        ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
            "globus_cond_init", gResult);
        goto error;
    }
    return NGEM_SUCCESS;

error:
    if (mutexInitialized) {
        gResult = globus_mutex_destroy(&op->ngo_mutex);
        if (gResult != GLOBUS_SUCCESS) {
            ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                "globus_mutex_destroy", gResult);
        }
    }
    return NGEM_FAILED;
}
예제 #5
0
/**
 * Socket:Write 
 * if nwrite < size, Canceled.
 */
ngemResult_t
ngrcSocketWrite(
    ngrcSocket_t *sock,
    void *buf,
    size_t size,
    size_t *nwrite)
{
    fd_set rfds;
    fd_set wfds;
    int result;
    ngLog_t *log;
    int fdmax;
    ssize_t nw = 0;
    size_t sum = 0;
    NGEM_FNAME(ngrcSocketWrite);

    NGEM_ASSERT(sock != NULL);
    NGEM_ASSERT(buf != NULL);
    NGEM_ASSERT(size > 0);
    NGEM_ASSERT(nwrite != NULL);

    *nwrite = 0;

    log = ngemLogGetDefault();

    while (sum < size) {
        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        FD_SET(sock->ngs_fd, &wfds);
        FD_SET(NGEM_PIPE_IN(sock->ngs_pipe), &rfds);

        fdmax = NGEM_MAX(sock->ngs_fd, NGEM_PIPE_IN(sock->ngs_pipe)) + 1;

        result = select(fdmax, &rfds, &wfds, NULL, NULL);
        if (result < 0) {
            if (errno == EINTR) {
                continue;
            }
            ngLogError(log, NGRC_LOGCAT_GT, fName,
                "select: %s\n", strerror(errno));
            return NGEM_FAILED;
        }

        if (FD_ISSET(NGEM_PIPE_IN(sock->ngs_pipe), &rfds)) {
            /* Not continue */
            *nwrite = sum;
            return NGEM_SUCCESS;
        }

        if (FD_ISSET(sock->ngs_fd, &wfds)) {
            nw = write(sock->ngs_fd, ((char *)buf)+sum, size-sum);
            if (nw < 0) {
                if (errno == EAGAIN) {continue;}
                ngLogError(log, NGRC_LOGCAT_GT, fName,
                    "write: %s\n", strerror(errno));
                return NGEM_FAILED;
            }
            sum += nw;
            NGEM_ASSERT(sum <= size);
        }
    }
    *nwrite = sum;

    return NGEM_SUCCESS;
}
예제 #6
0
/**
 * Socket: accept
 */
ngrcSocket_t *
ngrcSocketAccept(
    ngrcSocket_t *listener,
    bool *canceled)
{
    ngrcSocket_t *sock = NULL;
    int fd = -1;
    fd_set rfds;
    int result;
    ngLog_t *log;
    int fdmax;
    struct sockaddr_in addr; 
    ngiSockLen_t addr_len = sizeof(addr);
    NGEM_FNAME(ngrcSocketAccept);

    NGEM_ASSERT(listener != NULL);
    NGEM_ASSERT(canceled != NULL);

    *canceled = false;

    log = ngemLogGetDefault();

    while (fd < 0) {
        FD_ZERO(&rfds);
        FD_SET(listener->ngs_fd, &rfds);
        FD_SET(NGEM_PIPE_IN(listener->ngs_pipe), &rfds);

        fdmax = NGEM_MAX(listener->ngs_fd, NGEM_PIPE_IN(listener->ngs_pipe)) + 1;

        result = select(fdmax, &rfds, NULL, NULL, NULL);
        if (result < 0) {
            if (errno == EINTR) {
                continue;
            }
            ngLogError(log, NGRC_LOGCAT_GT, fName,
                "select: %s\n", strerror(errno));
            goto error;
        }

        if (FD_ISSET(NGEM_PIPE_IN(listener->ngs_pipe), &rfds)) {
            /* Not continue */
            *canceled = true;
            return NULL;
        }

        if (FD_ISSET(listener->ngs_fd, &rfds)) {
            fd = accept(listener->ngs_fd, (struct sockaddr *)&addr, &addr_len);
            if (result < 0) {
                if (errno == EAGAIN) {continue;}
                ngLogError(log, NGRC_LOGCAT_GT, fName,
                    "accept: %s\n", strerror(errno));
                if (errno == EBADF) {
                    return NULL;
                }
                continue;
            }
        }
    }

    sock = ngrclSocketCreate(fd);
    if (sock == NULL) {
        ngLogError(log, NGRC_LOGCAT_GT, fName,
            "Can't create socket.\n");
        goto error;
    }

    return sock;
error:
    if (fd >= 0) {
        result = close(fd);
        if (result < 0) {
            ngLogError(log, NGRC_LOGCAT_GT, fName,
                "close: %s.\n", strerror(errno));
        }
    }

    return NULL;
}
예제 #7
0
/**
 * Operator: write
 */
ngemResult_t
ngrcOperatorWrite(
    ngrcOperator_t *op,
    void *buf,
    size_t size,
    size_t *nWrite,
    bool *canceled)
{
    globus_result_t gResult;
    ngemResult_t ret = NGEM_FAILED;
    bool locked = false;
    ngLog_t *log = NULL;
    ngrclOperatorCallbackArg_t arg;
    NGEM_FNAME(ngrcOperatorWrite);

    log = ngemLogGetDefault();

    NGEM_ASSERT(op != NULL);
    NGEM_ASSERT(size >= 0);
    NGEM_ASSERT(nWrite != NULL);
    NGEM_ASSERT(canceled != NULL);

    *canceled = false;

    gResult = globus_mutex_lock(&op->ngo_mutex);
    if (gResult != GLOBUS_SUCCESS) {
        ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
            "globus_mutex_lock", gResult);
        goto finalize;
    } 
    locked = true;

    ngrclOperatorCallbackArgInitialize(&arg, op);

    if (op->ngo_canceled) {
        *canceled = true;
    } else {

        ngLogDebug(log, NGRC_LOGCAT_GT, fName,
            "user_data = %p.\n", &arg);

        gResult = globus_xio_register_write(
            op->ngo_handle, buf, size, size, NULL,
            ngrclGlobusCallback, &arg);
        if (gResult != GLOBUS_SUCCESS) {
            ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                "globus_xio_register_write", gResult);
            goto finalize;
        }

        while (arg.ngoca_done == false) {
            gResult = globus_cond_wait(&op->ngo_cond, &op->ngo_mutex);
            if (gResult != GLOBUS_SUCCESS) {
                ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                    "globus_cond_wait", gResult);
            }
        }

        if (arg.ngoca_result != GLOBUS_SUCCESS) {
            if (globus_xio_error_is_canceled(arg.ngoca_result) == GLOBUS_FALSE) {
                ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                    "Callback function for writing", arg.ngoca_result);
                goto finalize;
            }
            *canceled = true;
        } else {
            ngLogDebug(log, NGRC_LOGCAT_GT, fName,
                "Writes %lu bytes\n", (unsigned long)arg.ngoca_bytes);
            *nWrite = arg.ngoca_bytes;
        }
    }

    ret = NGEM_SUCCESS;

finalize:
    ngrclOperatorCallbackArgFinalize(&arg);

    if (locked) {
        gResult = globus_mutex_unlock(&op->ngo_mutex);
        if (gResult != GLOBUS_SUCCESS) {
            ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                "globus_mutex_unlock", gResult);
            ret = NGEM_FAILED;
        }
        locked = false;
    }

    return ret;
}
예제 #8
0
/**
 * Operator: read
 */
ngemResult_t
ngrcOperatorRead(
    ngrcOperator_t *op,
    void *buf,
    size_t size,
    size_t *nRead,
    bool *canceled)
{
    ngemResult_t ret = NGEM_FAILED;
    globus_result_t gResult;
    ngLog_t *log = NULL;
    bool locked = false;
    ngrclOperatorCallbackArg_t arg;
    NGEM_FNAME(ngrcOperatorRead);

    log = ngemLogGetDefault();

    NGEM_ASSERT(op != NULL);
    NGEM_ASSERT(size >= 0);
    NGEM_ASSERT(nRead != NULL);
    NGEM_ASSERT(canceled != NULL);

    *canceled = false;

    gResult = globus_mutex_lock(&op->ngo_mutex);
    if (gResult != GLOBUS_SUCCESS) {
        ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
            "globus_mutex_lock", gResult);
        goto finalize;
    } 
    locked = true;

    ngrclOperatorCallbackArgInitialize(&arg, op);

    if (op->ngo_canceled) {
        *canceled = true;
        ret = NGEM_SUCCESS;
        goto finalize;
    }

    gResult = globus_xio_register_read(
        op->ngo_handle, buf, size, 1, NULL,
        ngrclGlobusCallback, &arg);
    if (gResult != GLOBUS_SUCCESS) {
        ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
            "globus_xio_register_read", gResult);
        goto finalize;
    }

    while (arg.ngoca_done == false) {
        gResult = globus_cond_wait(&op->ngo_cond, &op->ngo_mutex);
        if (gResult != GLOBUS_SUCCESS) {
            ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                "globus_cond_wait", gResult);
        }
    }

    if (arg.ngoca_result != GLOBUS_SUCCESS) {
        if (globus_xio_error_is_canceled(arg.ngoca_result) == GLOBUS_TRUE) {
            *canceled = true;
        } else if (globus_xio_error_is_eof(arg.ngoca_result) == GLOBUS_TRUE) {
            *nRead = 0;
        } else {
            ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                "Callback function for reading", arg.ngoca_result);
            goto finalize;
        }
    } else {
        *nRead = arg.ngoca_bytes;
        NGEM_ASSERT(*nRead > 0);
    }

    ret = NGEM_SUCCESS;
finalize:
    ngrclOperatorCallbackArgFinalize(&arg);

    if (locked) {
        gResult = globus_mutex_unlock(&op->ngo_mutex);
        if (gResult != GLOBUS_SUCCESS) {
            ngcpLogGlobusError(log, NGRC_LOGCAT_GT, fName,
                "globus_mutex_unlock", gResult);
            ret = NGEM_FAILED;
        }
        locked = false;
    }

    return ret;
}