コード例 #1
0
static void
open_cb(
    globus_xio_handle_t                         handle,
    globus_result_t                             result,
    void *                                      user_arg)
{
    globus_result_t                             res;
    int                                         ctr;
    test_info_t *                               info;
    globus_bool_t                               data = GLOBUS_FALSE;

    info = (test_info_t *) user_arg;

    test_res(GLOBUS_XIO_TEST_FAIL_FINISH_OPEN, result, __LINE__, __FILE__);

    globus_mutex_lock(&info->mutex);
    {
        for(ctr = 0; ctr < info->write_count; ctr++)
        {
            res = globus_xio_register_write(
                      handle,
                      info->buffer,
                      info->buffer_length,
                      info->buffer_length,
                      NULL,
                      write_cb,
                      user_arg);
            test_res(GLOBUS_XIO_TEST_FAIL_PASS_WRITE, res, __LINE__, __FILE__);
            data = GLOBUS_TRUE;
        }

        for(ctr = 0; ctr < info->read_count; ctr++)
        {
            res = globus_xio_register_read(
                      handle,
                      info->buffer,
                      info->buffer_length,
                      info->buffer_length,
                      NULL,
                      read_cb,
                      user_arg);
            test_res(GLOBUS_XIO_TEST_FAIL_PASS_READ, res, __LINE__, __FILE__);
            data = GLOBUS_TRUE;
        }

        if(!data)
        {
            res = globus_xio_register_close(
                      handle,
                      NULL,
                      close_cb,
                      user_arg);
            test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);
        }
    }
    globus_mutex_unlock(&info->mutex);
}
コード例 #2
0
ファイル: space_test.c プロジェクト: bbockelm/globus-toolkit
static void
open_cb(
    globus_xio_handle_t                         handle,
    globus_result_t                             result,
    void *                                      user_arg)
{
    globus_result_t                             res;
    globus_byte_t *                             buffer;
    globus_size_t                               buffer_length;
    globus_size_t                               nbytes;
    int                                         ctr;

    buffer = globus_l_test_info.buffer;
    buffer_length = globus_l_test_info.buffer_length;

    globus_mutex_lock(&globus_l_mutex);
    {
        for(ctr = 0; ctr < OP_COUNT; ctr++)
        {
            res = globus_xio_register_write(
                    handle,
                    buffer,
                    buffer_length,
                    buffer_length,
                    NULL,
                    data_cb,
                    user_arg);
            test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);
            res = globus_xio_register_read(
                    handle,
                    buffer,
                    buffer_length,
                    buffer_length,
                    NULL,
                    data_cb,
                    user_arg);
            test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);

            res = globus_xio_write(
                    handle,
                    buffer,
                    buffer_length,
                    buffer_length,
                    &nbytes,
                    NULL);
            res = globus_xio_read(
                    handle,
                    buffer,
                    buffer_length,
                    buffer_length,
                    &nbytes,
                    NULL);
        }
    }
    globus_mutex_unlock(&globus_l_mutex);
}
コード例 #3
0
static void
write_cb(
    globus_xio_handle_t                         handle,
    globus_result_t                             result,
    globus_byte_t *                             buffer,
    globus_size_t                               len,
    globus_size_t                               nbytes,
    globus_xio_data_descriptor_t                data_desc,
    void *                                      user_arg)
{
    test_info_t *                               info;
    globus_result_t                             res;

    if(!globus_xio_error_is_canceled(result))
    {
        test_res(GLOBUS_XIO_TEST_FAIL_FINISH_WRITE, result, __LINE__, __FILE__);
    }

    info = (test_info_t *) user_arg;

    globus_mutex_lock(&info->mutex);
    {
        if(len < nbytes)
        {
            failed_exit("write wait for has failed");
        }
        else if(nbytes > len)
        {
            failed_exit("too many bytes were written.");
        }

        info->nwritten += nbytes;

        if(info->nwritten >= info->total_write_bytes && !info->write_done)
        {
            info->closed++;
            info->write_done = GLOBUS_TRUE;
            if(info->closed == 2 || info->read_count == 0)
            {
                res = globus_xio_register_close(
                          handle,
                          NULL,
                          close_cb,
                          user_arg);
                test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);
            }
        }
        else if(!info->write_done)
        {
            res = globus_xio_register_write(
                      handle,
                      info->buffer,
                      info->buffer_length,
                      info->buffer_length,
                      NULL,
                      write_cb,
                      user_arg);
            test_res(GLOBUS_XIO_TEST_FAIL_PASS_WRITE, res, __LINE__, __FILE__);
        }
    }
    globus_mutex_unlock(&info->mutex);
}
コード例 #4
0
static
void
state_machine(
    void *                              user_arg)
{
    globus_reltime_t                    delay;
    globus_result_t                     result;
    globus_l_timeout_info_t *           info = user_arg;

    /* If the timeout is to be caused by this side of the transfer, then check
     * current state, and if it's the timeout state, then we'll clear the
     * cause_timeout flag and then reregister this oneshot with the delay of
     * (timeout * 5) and continue the state machine.
     */

    globus_mutex_lock(&lock);
    if (info->cause_timeout && info->timeout_state == info->state)
    {
        /* register oneshot at (timeout * 5) */
        GlobusTimeReltimeSet(delay,
                0,
                (info->timeout * 5 * 1000));

        info->cause_timeout = GLOBUS_FALSE;
        info->state = GLOBUS_XIO_OPERATION_TYPE_CLOSE;

        globus_callback_register_oneshot(
                NULL,
                &delay,
                state_machine,
                info);
        globus_mutex_unlock(&lock);
        return;
    }

    /* process current state */
    switch (info->state)
    {
        case GLOBUS_XIO_OPERATION_TYPE_ACCEPT:
            globus_assert(info->server);
            result = globus_xio_server_register_accept(
                    info->server,
                    accept_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_OPEN:
            result = globus_xio_register_open(
                    info->handle,
                    info->contact,
                    info->attr,
                    open_close_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_READ:
            result = globus_xio_register_read(
                    info->handle,
                    info->buffer,
                    sizeof(info->buffer),
                    1,
                    NULL,
                    data_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_WRITE:
            strcpy((char *) info->buffer, "ok\n");

            result = globus_xio_register_write(
                    info->handle,
                    info->buffer,
                    strlen((char *) info->buffer),
                    strlen((char *) info->buffer),
                    NULL,
                    data_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_CLOSE:
            result = globus_xio_register_close(
                    info->handle,
                    NULL,
                    open_close_callback,
                    info);
            break;

        case GLOBUS_XIO_OPERATION_TYPE_FINISHED:
            globus_cond_signal(&cond);
            info->state = GLOBUS_XIO_OPERATION_TYPE_NONE;
            break;

        case GLOBUS_XIO_OPERATION_TYPE_NONE:
        case GLOBUS_XIO_OPERATION_TYPE_DRIVER:
        case GLOBUS_XIO_OPERATION_TYPE_DD:
        case GLOBUS_XIO_OPERATION_TYPE_SERVER_INIT:
            fprintf(stderr,
                    "Error: unexpected state: %d\n",
                    info->state);
            info->result = GLOBUS_FAILURE;
            info->state = GLOBUS_XIO_OPERATION_TYPE_NONE;
            globus_cond_signal(&cond);
            break;
    }
    globus_mutex_unlock(&lock);
}
コード例 #5
0
int
main(
    int                                     argc,
    char **                                 argv)
{
    globus_xio_stack_t                      stack;
    globus_xio_stack_t                      mode_e_stack;
    globus_xio_handle_t                     xio_handle;
    globus_xio_server_t			    server;	
    globus_xio_attr_t                       attr = NULL;
    char *                                  cs = NULL;
    globus_result_t                         res;
    int                                     ctr;
    int					    num_streams = 1;
    globus_bool_t                           be_server = GLOBUS_FALSE;
    int                                     rc;
    char				    filename[FILE_NAME_LEN];
    FILE *				    fp;

    rc = globus_module_activate(GLOBUS_XIO_MODULE);
    globus_assert(rc == GLOBUS_SUCCESS);

    res = globus_xio_driver_load("mode_e", &mode_e_driver);
    test_res(res);
    res = globus_xio_driver_load("ordering", &ordering_driver);
    test_res(res);
    res = globus_xio_stack_init(&stack, NULL);
    test_res(res);
    res = globus_xio_stack_push_driver(stack, mode_e_driver);
    test_res(res);
    res = globus_xio_stack_push_driver(stack, ordering_driver);
    test_res(res);
    res = globus_xio_driver_load("tcp", &tcp_driver);
    test_res(res);                      
    res = globus_xio_stack_init(&mode_e_stack, NULL);
    test_res(res);
    res = globus_xio_stack_push_driver(mode_e_stack, tcp_driver);
    test_res(res);

    if (argc < 4)
    {
        help();
        exit(1);
    }
    test_res(globus_xio_attr_init(&attr));
    test_res(globus_xio_attr_cntl(
        attr,
        mode_e_driver,
        GLOBUS_XIO_MODE_E_SET_STACK,
        mode_e_stack));
    for(ctr = 1; ctr < argc; ctr++)
    {
        if(strcmp(argv[ctr], "-h") == 0)
        {
            help();
            return 0;
        }
        else if(strcmp(argv[ctr], "-c") == 0)
        {
	    if (argc < 5)
	    {
		help();
		exit(1);
	    }
            cs = argv[ctr + 1];
            ctr++;
        }
        else if(strcmp(argv[ctr], "-s") == 0)
        {
            be_server = GLOBUS_TRUE;
        }
        else if(strcmp(argv[ctr], "-p") == 0)
        {
            if (argc < 6)
            {
                help();
                exit(1);
            }
            port = atoi(argv[ctr+1]);
        /*    test_res(globus_xio_attr_cntl(
                attr,
                mode_e_driver,
                GLOBUS_XIO_MODE_E_APPLY_ATTR_CNTLS,
                attr_cntl_cb));*/
        }
        else if(strcmp(argv[ctr], "-P") == 0)
        {
	    if (argc < 6)
	    {
		help();
		exit(1);
	    }
            num_streams = atoi(argv[ctr+1]);
            test_res(globus_xio_attr_init(&attr));
            test_res(globus_xio_attr_cntl(
                attr,
                ordering_driver,
		GLOBUS_XIO_ORDERING_SET_MAX_READ_COUNT,
                num_streams));
            test_res(globus_xio_attr_cntl(
                attr,
                mode_e_driver,
                GLOBUS_XIO_MODE_E_SET_NUM_STREAMS,
                num_streams));
        } 
	else if(strcmp(argv[ctr], "-f") == 0)
	{
	    if (ctr + 1 < argc)
	    {
	        strcpy(filename, argv[ctr + 1]);
	    }
	    else	
	    {
		help();
		exit(1);
	    }
	}
    }
    
    if (!be_server && (!cs || !*cs))
    {
        help();
        exit(1);
    }
    
    if(be_server)
    {
	globus_size_t size = CHUNK_SIZE + 1;
	int i, nbytes;
	res = globus_xio_server_create(&server, attr, stack);
    	test_res(res);
        globus_xio_server_get_contact_string(server, &cs);
        fprintf(stdout, "Contact: %s\n", cs);   
	res = globus_xio_server_accept(&xio_handle, server);
    	test_res(res);
	res = globus_xio_open(xio_handle, NULL, attr);
	test_res(res);
 	fp = fopen(filename, "w");
        while(1)
        {
	    char * buffer;
	    buffer = (char *) globus_malloc(size);
            for (i=0; i<size; i++)
		buffer[i] = '\0';
            res = globus_xio_read(
                xio_handle,
                buffer,
                size - 1,
		1,
		&nbytes,
                NULL);
	    fputs(buffer, fp);
	    if (res != GLOBUS_SUCCESS)
		break;
	}
	res = globus_xio_close(xio_handle, NULL);
	test_res(res);
        res = globus_xio_server_close(server);
	test_res(res);
	res = globus_xio_driver_unload(mode_e_driver);
	test_res(res);
	rc = globus_module_deactivate(GLOBUS_XIO_MODULE);
	globus_assert(rc == GLOBUS_SUCCESS);
        
    }
    else
    {
	globus_size_t 			size = CHUNK_SIZE + 1;
        int	                        nbytes;
        int				i,x;
        res = globus_xio_handle_create(&xio_handle, stack);
        test_res(res);
        res = globus_xio_stack_destroy(stack);
        test_res(res);
   	res = globus_xio_open(xio_handle, cs, attr);
   	test_res(res);
        globus_mutex_init(&mutex, NULL);
        globus_cond_init(&cond, NULL);

        fp = fopen(filename, "r");
        globus_mutex_lock(&mutex);
        while(!feof(fp))
	{
            char * buffer;
	    buffer = (char *) globus_malloc(size);
 	    for (i = 0; i < size; i++)
                buffer[i] = '\0';
	    x = fread(buffer, CHUNK_SIZE, 1, fp);
            nbytes = strlen(buffer);
            res = globus_xio_register_write(
                xio_handle,
                buffer,
                nbytes,
                nbytes,
                NULL,
		write_cb,
		NULL);
            test_res(res); 
	    ++y;
        } 
        fclose(fp);
/*        test_res(globus_xio_data_descriptor_init(&dd, xio_handle));
        test_res(globus_xio_data_descriptor_cntl(
            dd,
            mode_e_driver,
            GLOBUS_XIO_MODE_E_SEND_EOD,
            GLOBUS_TRUE));
        res = globus_xio_write(
                xio_handle,
                buffer,
                nbytes,
                nbytes,
                &nbytes,
                NULL);
        test_res(res); */
        while(y)
        {
            globus_cond_wait(&mutex, &cond);
        }
        globus_mutex_unlock(&mutex);
	res = globus_xio_close(xio_handle, attr);
	test_res(res);
	res = globus_xio_driver_unload(mode_e_driver);
	test_res(res);
	res = globus_xio_driver_unload(ordering_driver);
	test_res(res);
	rc = globus_module_deactivate(GLOBUS_XIO_MODULE);
	globus_assert(rc == GLOBUS_SUCCESS);
        globus_mutex_destroy(&mutex);
        globus_cond_destroy(&cond);

    }
    return 0;
}
コード例 #6
0
ファイル: cancel_test.c プロジェクト: bbockelm/globus-toolkit
static void
open_cb(
    globus_xio_handle_t                         handle,
    globus_result_t                             result,
    void *                                      user_arg)
{
    globus_result_t                             res;
    globus_byte_t *                             buffer;
    globus_size_t                               buffer_length;
    char *                                      timeout_type;
    int                                         mask = 0;

    buffer = globus_l_test_info.buffer;
    buffer_length = globus_l_test_info.buffer_length;

    timeout_type = (char *) user_arg;
    if(strcmp(timeout_type, "O") == 0)
    {
        if(!result_is_cancel(result))
        {
            failed_exit("Open was not canceled.");
        }
        else
        {
            globus_mutex_lock(&globus_l_mutex);
            {
                globus_l_closed = GLOBUS_TRUE;
                globus_cond_signal(&globus_l_cond);
            }
            globus_mutex_unlock(&globus_l_mutex);
        }
    }
    else
    {
        if(globus_l_test_info.write_count > 0)
        {
            res = globus_xio_register_write(
                    handle,
                    buffer,
                    buffer_length,
                    buffer_length,
                    NULL,
                    data_cb,
                    user_arg);
            mask = GLOBUS_XIO_CANCEL_WRITE;
        }
        else
        {
            res = globus_xio_register_read(
                    handle,
                    buffer,
                    buffer_length,
                    buffer_length,
                    NULL,
                    data_cb,
                    user_arg);
            mask = GLOBUS_XIO_CANCEL_READ;
        }
        test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);
        if(strcmp(timeout_type, "D") == 0)
        {
            res = globus_xio_handle_cancel_operations(
                    handle,
                    mask);
            test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);
        }
    }
}
コード例 #7
0
static void
open_cb(
    globus_xio_handle_t                         handle,
    globus_result_t                             result,
    void *                                      user_arg)
{
    globus_result_t                             res;
    globus_byte_t *                             buffer;
    globus_size_t                               buffer_length;
    char *                                      timeout_type;

    buffer = globus_l_test_info.buffer;
    buffer_length = globus_l_test_info.buffer_length;

    timeout_type = (char *) user_arg;
    globus_mutex_lock(&globus_l_mutex);
    {
        if(strcmp(timeout_type, "O") == 0)
        {
            if(!result_is_timeout(result) && globus_l_timeout)
            {
                failed_exit("Open did not timeout.");
            }
            else if(result == GLOBUS_SUCCESS)
            {
                res = globus_xio_register_close(
                        handle,
                        NULL,
                        close_cb,
                        user_arg);
                test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);
            }
            else
            {
                globus_l_closed = GLOBUS_TRUE;
                globus_cond_signal(&globus_l_cond);
            }
        }
        else
        {
            if(globus_l_test_info.write_count > 0)
            {
                res = globus_xio_register_write(
                        handle,
                        buffer,
                        buffer_length,
                        buffer_length,
                        NULL,
                        data_cb,
                        user_arg);
            }
            else
            {
                res = globus_xio_register_read(
                        handle,
                        buffer,
                        buffer_length,
                        buffer_length,
                        NULL,
                        data_cb,
                        user_arg);
            }
            test_res(GLOBUS_XIO_TEST_FAIL_NONE, res, __LINE__, __FILE__);
        }
    }
    globus_mutex_unlock(&globus_l_mutex);
}
コード例 #8
0
static
void
gfs_l_xio_cp_read_cb(
    globus_xio_handle_t                 handle,
    globus_result_t                     result,
    globus_byte_t *                     buffer,
    globus_size_t                       len,
    globus_size_t                       nbytes,
    globus_xio_data_descriptor_t        data_desc,
    void *                              user_arg)
{
    gfs_l_xio_read_buffer_t *           read_buf;
    gfs_i_xio_cp_handle_t *             cp_h;

    read_buf = (gfs_l_xio_read_buffer_t *) user_arg;
    cp_h = read_buf->whos_my_daddy;

    globus_mutex_lock(&cp_h->mutex);
    {
        read_buf->nbytes = nbytes;
        if(result != GLOBUS_SUCCESS)
        {
            if(eof)
            {
                read_buf->eof = GLOBUS_TRUE;
            }
            else
            {
                /* what if this is just EOF */
                goto error;
            }
        }
        /* it is possible to get here in the CLOSING state without an error */
        if(cp_h->state == GFS_CIO_CP_STATE_ERROR)
        {
            goto error;
        }

        /* XXX need to get an offset for this buffer */
        read_buf->nbytes = nbytes;
        result = globus_xio_data_descriptor_cntl(
            data_desc,
            NULL,
            GLOBUS_XIO_DD_GET_OFFSET,
            &offset);
        if(result != GLOBUS_SUCCESS)
        {
            goto error;
        }
        read_buf->offset = offset;

        if(!globus_fifo_empty(cp_h->write_q))
        {
            read_buf->write_xio = 
                (globus_xio_handle_t) globus_fifo_dequeue(cp_h->write_q);
            result = globus_xio_handle_cntl(
                read_buf->write_xio,
                GLOBUS_XIO_QUERY,
                GLOBUS_XIO_SEEK,
                read_buf->offset);
            if(result != GLOBUS_SUCCESS)
            {
                goto error;
            }

            result = globus_xio_register_write(
                read_buf->write_xio,
                read_buf->buffer,
                read_buf->nbytes,
                read_buf->nbytes,
                NULL,
                gfs_l_xio_cp_write_cb,
                read_buf);
            if(result != GLOBUS_SUCCESS)
            {
                goto error;
            }
        }
        else
        {
            /* stick this one in the queue */
            globus_fifo_enqueue(&cp_h->read_buffer_q, read_buf);
        }

        if(!eof)
        {
            /* make and post a new one */
            read_buf = (gfs_l_xio_read_buffer_t *)
                globus_calloc(sizeof(gfs_l_xio_read_buffer_t)+block_size, 1);
            read_buf->block_size = cp_h->block_size;
            read_buf->whos_my_daddy = cp_h;
            /* do this last since it can inspire the CLOSING state */
            gfs_l_xio_cp_post_read(xio_h, read_buf);
        }
        else
        {
            /* remove it from close q and close */
            globus_fifo_remove(cp_h->read_all_q, read_buf->read_xio);
            result = globus_xio_register_close(
                read_buf->read_xio,
                NULL,
                gfs_l_xio_cp_close_cb,
                cp_h);
            if(result != GLOBUS_SUCCESS)
            {
                cp_h->read_handle_count--;
            }
            if(cp_h->read_handle_count <= 0)
            {
                gfs_l_xio_close_write_handles(cp_h);
            }
        }
    }
    globus_mutex_unlock(&cp_h->mutex);

    return;

error:
    globus_free(read_buf);
    gfs_l_xio_cp_error(cp_h, result);
    globus_mutex_unlock(&cp_h->mutex);
}
コード例 #9
0
static
void
gfs_l_xio_cp_write_cb(
    globus_xio_handle_t                 handle,
    globus_result_t                     result,
    globus_byte_t *                     buffer,
    globus_size_t                       len,
    globus_size_t                       nbytes,
    globus_xio_data_descriptor_t        data_desc,
    void *                              user_arg)
{
    gfs_l_xio_read_buffer_t *           read_buf;
    gfs_i_xio_cp_handle_t *             cp_h;

    read_buf = (gfs_l_xio_read_buffer_t *) user_arg;
    cp_h = read_buf->whos_my_daddy;
    globus_free(read_buf);

    globus_mutex_lock(&cp_h->mutex);
    {
        if(result != GLOBUS_SUCCESS)
        {
            goto error;
        }
        if(cp_h->state == GFS_CIO_CP_STATE_ERROR)
        {
            goto error;
        }

        /* if there are outstanding read buffers left use this handle
            to write one */
        if(!globus_fifo_empty(cp_h->read_buffer_q))
        {
            read_buf = (gfs_l_xio_read_buffer_t *)
                globus_fifo_dequeue(&cp_h->write_q);

            globus_xio_handle_cntl(
                read_buf->write_xio,
                NULL, /* QUERY MAYBE? */
                GLOBUS_XIO_SEEK,
                read_buf->offset);

            result = globus_xio_register_write(
                read_buf->write_xio,
                read_buf->buffer,
                read_buf->nbytes,
                read_buf->nbytes,
                NULL,
                gfs_l_xio_cp_write_cb,
                read_buf);
            if(result != GLOBUS_SUCCESS)
            {
                goto error;
            }
        }
        /* if read buffers are gone and all read handles are gone
            then we are at eof and can start cloising the writes */
        else if(globus_fifo_empty(cp_h->read_all_q))
        {
            gfs_l_xio_close_write_handles(cp_h);
        }
        /* if still going but nothing to write just put this back in the
            queue */
        else
        {
            globus_fifo_enqueue(&cp_h->write_q, read_buf->write_xio);
        }
    }
    globus_mutex_unlock(&cp_h->mutex);

    if(cp_h->update_cb)
    {
        cp_h->update_cb(offset, nbytes, cp_h->user_arg);
    }

    return;

error:

    globus_free(read_buf);
    gfs_l_xio_cp_error(cp_h, result);
    globus_mutex_unlock(&cp_h->mutex);
}
コード例 #10
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;
}