UTL_TCP (blocking or non-blocking sockets mode)

Hi for All,
Please, someone knows if the UTL_TCP using blocking or non-blocking sockets mode? I did a search but can not find this information.
Regards,

Blocking only occurs when you attempt to read from the socket and there's no data to read. (in which case, the time out setting applies if specified)
This is however not that robust in my experience. UTL_TCP provides a peek method (returns byte size of socket buffer) that tells you whether or not there is data for that socket. This enables you to verify that you read on that socket will not be a blocking call.
I prefer using this method, as dealing with a timeout approach results in run-time behaviour issues (either a call waiting too long, or a call timing out too quickly).

Similar Messages

  • Both blocking and non-blocking io

    I'm wondering if this scenario is possible with the new nio classes:
    I have a caching server. Clients connect to the server and occasionally send requests for objects. I'd like to use the nio non-blocking APIs to detect that there is a read pending on a socket. However, once I detect this, I'd like to go into a blocking loop to process the request. After this done, I'd like to go back into non-blocking mode and wait for another request.
    It seems like this should be possible but the (woefully lacking) documentation isn't clear. Neither is the source code, apparently.
    I've got a test case working but I was hoping someone could validate for me that this is support behavior. It's done by waiting for the isReadable() key then calling socket.keyFor(selector).cancel(); and then socket.configureBlocking(true); The reads are then done in blocking mode until the request is done and then the socket is registered with the selector again.
    Thanks for any help on this.

    I have to ask why you would want to mix blocking and non-blocking I/O.
    The only reason you would (IMHO) want to use non-blocking I/O is in a highly concurrent system, to increase the maximum load a system can handle.
    The main reason you would want to use blocking I/O rather than non-blocking I/O would be to minimise the latency for a single request.
    Unfortunately, the two don't seem to mix together very well... by switching a thread to blocking, you decrease the latency for a single request, but increase latency for the other requests due to reduced resources available. Similarly, by switching to blocking, you are requiring a dedicated thread for that request, so limiting the number of concurrent requests that can be serviced.
    That is, it seems to me that using both blocking and non-blocking I/O introduces the weaknesses of both into the system, without gaining much of the benefits of either.
    The above aside, the method you gave looks like it would work as you expect, depending on what you are doing with thread creation/delegation. Did your test case work as expected?

  • SQL Developer blocking vs non-blocking

    Hi,
    Is there a way in SQL Developer 3.0 to have a non-blocking SQL call? In Oracle Forms we can choose between blocking and non-blocking SQL Net connections to the database. Does SQL Developer have the same capability? If so where exactly are those options hidden in the preferences menus?
    Annoyed,
    ScottK
    Edited by: ScottK on Jun 1, 2011 11:20 AM

    Hi ScottK,
    SQLDeveloper locks access to individual connections when they are in use, if you want to simulate
    some aspects of non blocking behaviour you can use other connections.
    The following features might help:
    Use a different connection name back to the same schema in your database - it will be treated as an independent connection and 'blocking' on this connection will not affect your other connections.
    This can be achieved temporarily in the worksheet by:
    ctrl shift n
    which creates a worksheet with new connection independent of your existing worksheet connection
    though connected to the same schema and database.
    -Turloch
    SQLDeveloper team

  • Blocking and non-blocking workflows

    How to specify a workflow to be blocking and non-blocking?
    Regards,
    Miguel

    When registering the custom workflow from Application Server Control (Enterprise Manager Web Site), you will see an option to specify whether the workflow is blocking:
    Application Server Control > Content > Custom Workflows
    Register Workflow
    * Name  
      Description  
    * Launch Event  
    * Cancel Event  
      Blocking
      Approvers Required

  • Easy way to non-blocked sockets

    Use JSSE and NIO for a quick way to implement non-blocking communications
    October 22, 2003
    Although SSL blocking operations -- in which the socket is blocked from access while data is being read from or written to -- provide better I/O-error notification than the non-blocking counterpart, non-blocking operations allow the calling thread to continue. In this article, the author will cover both the client and server side as he describes how to create non-blocking secure connections using the Java Secure Socket Extensions (JSSE) and the Java NIO (new I/O) library, and he will explain the traditional approach to creating a non-blocking socket, as well as an alternative (and necessary) method if you want to use JSSE with NIO.
    http://www-106.ibm.com/developerworks/java/library/j-sslnb.html?ca=dgr-jw03j-sslnb

    MORE IBM SPAM Previous discussion
    I find it interesting spam, but thats a matter of taste. If the OP was truly interested in "trying to get new information out there" he would answer the mulitple questions about NIO and especially NIO mixed with traditional Sockets and NIO vs Secure Sockets. These are all on ALT, NIO is of no interest to New to Java folk.
    Given their budget I think IBM could do a better job of publishing their research.

  • Non-blocking SocketChannel and close - huh?

    It looks like closing a socketchannel that is in non-blocking mode can result in a dead drop of the connection, with some bytes that have already been sent and accepted (as in, 'consumed' from the buffer) being completely dropped.
    In fact, I'm generally confused: Actual C non-blocking code has a similar setup for 'close' as you can see in SocketChannel's OP_CONNECT behaviour - just because you want to connect the socket doesn't mean it magically happends without blocking. Wait for a ready flag, then try again.
    It should work the same way with close (you try to close, but it may not be possible without blocking).
    Is this a huge gaping bug that no one quite figured out just yet, or did I miss something? I loathe to turn on linger, as that's just a crapshoot (you never know if it actually gets through. You could run into funny surprises once the server gets a bit busy. I'd rather not) and tends to cause massive leaks on linux, at least according to some google searches.
    There seems to be slightly better performance (in that I have always received all data sofar) if I close the socket instead of the channel (socketChannel.socket().close() instead of socketChannel.close()) - but this has been a random attempt at 'making it work', and I can't find any documentation that backs up that this will DEFINITELY not lose any information without letting me know somehow. That still sounds impossible with this approach.

    Actual C non-blocking code has a similar setup for
    'close' as you can see in SocketChannel's
    OP_CONNECT behaviour ...No it doesn't. I don't know what you mean by this.
    Closing a socket is asynchronous, but it shouldn't lose any data - if the data can be delivered it will be, followed by the FIN. You don't know when it is delivered, and you don't get to hear about any errors such as an RST coming from the other end, say if it decided to close before reading all the data, or if some intermediate router hung you up.
    I'm wondering if you are really dealing with all the short write and zero length write possibilities, i.e. whether the data isn't really still in your output buffer. Don't wish to teach you to suck eggs but there are some subtleties here.
    Setting a positive linger timeout doesn't really help because Java doesn't tell you if the timeout expired. (I only asked for this about four years ago). You get to wait while any pending data is delivered, but you still have to guess about whether it all went or the timeout expired, and the behaviour after the timeout expires is platform-dependent: some (Windows) issue an RST, others (Unix) keep trying.
    Blocking or non-blocking mode shouldn't make any difference to this (except that Linux will block on a positive linger timeout even in non-blocking mode, which is wrong), and whether you close the channel or the socket is immaterial as one calls the other anyway.
    The reason why OP_CONNECT is different in blocking/non-blocking modes is that in blocking mode it won't return until the SYN-ACK is received, while in non-blocking mode it just sends the SYN and relies on you calling connect() again (at the C level) to collect the SYN-ACK, or not - this is what finishConnect() tells you.
    tends to cause massive leaks on linux, at least
    according to some google searchesIt can't, unless you are referring to the Helix client thing, which appears to be just a badly designed C++ class library with, for some reason, its own linger implementation outside the kernel.

  • Sockets in non-blocking mode

    Hello Techies,
    How to set sockets in the non-blocking mode and what is the main use of setting sockets in non-blocking mode.
    regards,
    Ramu.

    Hello Techies,
    Thanks for u r replies,
    Finally i had understood how to use nio. But the problem is it is going into infinite loop. Here is my code.
    package networking;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.SocketChannel;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.util.Iterator;
    public class testSocketChannel {
          * @param args
         public static ByteBuffer buf ;
         public static SocketChannel clientChannel;
         public static void main(String[] args) {
              // TODO Auto-generated method stub
                        try
                             Selector selector = Selector.open();
                         clientChannel = SocketChannel.open();
                      clientChannel.configureBlocking(false);
                      // Send a connection request to the server; this method is non-blocking
                      clientChannel.connect(new InetSocketAddress("localhost",90));
                      clientChannel.register(selector,clientChannel.validOps());
    //                Wait for events
                      while (true)
                          try {
                              // Wait for an event
                              selector.select();
                          } catch (IOException e) {
                              // Handle error with selector
                              //break;
                          // Get list of selection keys with pending events
                          Iterator it = selector.selectedKeys().iterator();
                          // Process each key at a time
                          //while (it.hasNext())
                               for(int i = 0;i<selector.selectedKeys().size();i++)
                              // Get the selection key
                              SelectionKey selKey = (SelectionKey)it.next();
                              // Remove it from the list to indicate that it is being processed
                              it.remove();
                              try
                          //  processSelectionKey(selKey);
                                    if (selKey.isValid() && selKey.isConnectable()) {
                                       // Get channel with connection request
                                       SocketChannel sChannel = (SocketChannel)selKey.channel();
                                       boolean success = sChannel.finishConnect();
                                       if (!success) {
                                           // An error occurred; handle it
                                           // Unregister the channel with this selector
                                           selKey.cancel();
                                   if (selKey.isValid() && selKey.isReadable()) {
                                       // Get channel with bytes to read
                                        clientChannel = (SocketChannel)selKey.channel();
                                       System.out.println("INSIDE reading");
                                       // See e174 Reading from a SocketChannel
                                       // Clear the buffer and read bytes from socket
    //                                 Clear the buffer and read bytes from socket
                                      // ByteBuffer byteBuffer = ByteBuffer.allocate( BUFSIZE );
                                       buf = ByteBuffer.allocateDirect(1024);
                                       int nbytes = clientChannel.read( buf );
                                       buf.flip();
                                       Charset charset = Charset.forName( "us-ascii" );
                                       CharsetDecoder decoder = charset.newDecoder();
                                       CharBuffer charBuffer = decoder.decode( buf );
                                       String result = charBuffer.toString();
                                   if (selKey.isValid() && selKey.isWritable()) {
                                       // Get channel that's ready for more bytes
                                       //SocketChannel sChannel = (SocketChannel)selKey.channel();
                                       System.out.println("INSIDE writting");
                                       // See e175 Writing to a SocketChannel
                                     String message = "hi"; 
                                      buf = ByteBuffer.wrap( message.getBytes()  );
                                       int nbytes = clientChannel.write( buf );
                                       System.out.println( "Wrote " + nbytes + " to channel." );
                              catch (IOException e) {
                                       // TODO: handle exception
                                   System.out.println("IOException"+e.getMessage());
                        catch (IOException ioe) {
                             // TODO: handle exception
                             System.out.println("IOException"+ioe.getMessage());
    }How to stop this infinite loop.
    Need quick replies.
    Ramu

  • How to handle write errors in non blocking sockets

    Hi,
    I'm using sockets registered with a Selector for read operations. I've seen code examples that put the SocketChannel in non blocking mode before registering it with the selector, and in fact not doing so would cause an IllegalBlockingModeException to be thrown.
    My problem is that I can't handle write errors. The call to write() returns inmediately without throwing any exception. Even worse, when the network timeout expires the selector wakes up and I get an exception on read(). So I can't tell the difference between a real read error and a write error.
    What can I do? Is there a magic method I haven't heard about?
    Thanks

    ejp wrote:
    OK, so what happens is this: you write from your ByteBuffer; if there is room in the socket send buffer, the data is transferred and the transfer count is returned. (If there isn''t, the write returns zero and nothing has happened.) Your application code then continues. Meanwhile TCP is trying to send the data in the send buffer and get an ACK from the peer. If the peer is down as per your test, eventually those write attempts will time out. You will then get a connection reset exception on the next read or write.
    Even worse, when the network timeout expires the selector wakes upCorrect, to tell you there is an error condition pending. This is good, not bad.You're right. This way my program can know that something happened.
    But I still don't understand what the difference between a failed write() and a failed read() is. I mean, the error condition may appear during a send attempt, or it may appear after sending. In both cases I get an error when trying to read. How can my program know if data have been received by the other end?
    Do I have to implement ACK messages in the application level protocol??? It'd be nice if TCP could do this for me...

  • Non-blocking io socket

    If you have a connection to on a non-blocking socket channel will the socket, is it possible that it will stop streaming all the data available into the buffer? If so how can you check that this has happened?
    If you buffer being used by the socket is full how can make sure the streaming stops so you can drain the buffer and get the remaining data without losing it from the channel.
    How can you check to see if a channel has no more data to give?
    Thank you.

    The sender's write method will block in blocking mode, or return zero in non-blocking mode, when the target's receive buffer and the sender's send buffer are both full. This is the only flow control available unless you implement something yourself. The only way to tell whether you have read everything the other end is sending is by getting an EOF when the other end closes the socket, unless you build something into your application protocol.

  • About NIO non-blocking socket write method behavior

    Hi all -
    I hope anyone could help in this issue.
    Assume you create a NIO socket and configure its channel in non blocking mode:
    channel.configureBlocking(false);
    then you write a byte buffer into it:
    int sentBytesNum = channel.write(byteBuffer);
    What are the possibilities of sentBytesNum value? I am sure of two possibilities, which are:
    - all data sent so sentBytesNum equals byteBuffer data size (limit minus position before sending) (after sending the limit and position of byteBuffer are the same)
    - no data is sent so sentBytesNum is zero and byteBuffer limit and postion did not change, so we shall use a write selector to test when the channel will be ready for write to write the data.
    What I am not sure about and need someone to confirm is the third possibility:
    - only a part of data is sent (according to the available free space of socket output buffer) so sentBytesNum is more than zero but less than data size and byteBuffer position is advanced by the value of sentBytesNum, might this possibility happen??
    If yes, so we should manage to hold the non sent part of byteBuffer till the channel becomes ready for write (we can know that using write selector) so we can write it to channel???
    Thanks for help,
    Rocka

    Yes, case three can occur. The usual NIO write loop looks like this:
    int count = 0;
    while (buf.position() > 0)
      buf.flip();
      count = ch.write(buf);
      buf.compact();
      if (count == 0)
        break;
    }This will run until buf.position() == 0 or count == 0. If the partial write case happens it will loop one more time and probably get a 0 count.
    At the end of the loop, if buf.position() > 0 there is still unwritten data and at this point you should register for OP_WRITE and return to the selector. Otherwise if there is no data unwritten you should deregister OP_WRITE as you have nothing to write and aren't interested in the event any longer.
    If you are reading something and writing at the same time the logic goes like this:
    while (inch.read(buf) >= 0 || buf.position() > 0)
      // etc
    }This will read until EOF occurs and either buf.position() is zero or a zero length write occurred.

  • SELECT of OCILobLocator in Non Blocking mode

    Hi all.
    I have problem:
    I try select BLOB field into OCILobLocator* buffer in Non Blocking mode, and receive 'ORA-03106: fatal two-task communication protocol error' sometimes.
    Details:
    Application contains two threads : 1. select blob field, 2. update it.
    I tried separate update and select to different apps (and run its in one time) - problem reproduced.
    problem reproduced for OCIStmtFetch and OCIStmtFetch2.
    If disable non blocking mode - problem disappear.
    if error appear - record level error code contains 1405. Need wait few minutes for error message appearing (~1 minute in my case).
    Using of OCI_DEFAULT in OCIDefineByPos instead OCI_DYNAMIC_FETCH don't solve problem.
    I use oracle server and client library with version 10.2.0.4
    Output sample:
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #877: 1405
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #54: 1405
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #877: 1405
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #54: 1405
    Can anybody help me ?
    m.b. exists workaround ?
    #include <iostream>
    #include <sstream>
    #include <assert.h>
    #include <oci.h>
    #define _DYN 1
    before run this test run next sql at DB:
    CREATE TABLE ADSERVERTEST_BLOB(id NUMBER(10), text BLOB);
    BEGIN
    FOR i IN 0..999 LOOP
    INSERT INTO ADSERVERTEST_BLOB(id, text) VALUES(i, utl_raw.cast_to_raw('init'));
    END LOOP;
    END;
    template<typename Type, unsigned long TypeId>
    class OCIHandlePtr
    public:
    OCIHandlePtr(): handle_(0) {}
    OCIHandlePtr(Type* handle): handle_(handle) {}
    ~OCIHandlePtr()
    reset(0);
    void reset(Type* handle)
    if(handle_)
    sword result;
    if((result = OCIHandleFree(
    handle_,
    TypeId)) != OCI_SUCCESS)
    assert(0);
    std::cerr << "Can't make OCIHandleFree" << std::endl;
    handle_ = handle;
    Type* get()
    return handle_;
    Type*& fill()
    reset(0);
    return handle_;
    private:
    Type* handle_;
    template<typename Type, unsigned long TypeId>
    class OCIDescriptorPtr
    public:
    OCIDescriptorPtr(): handle_(0) {}
    OCIDescriptorPtr(Type* handle): handle_(handle) {}
    ~OCIDescriptorPtr()
    reset(0);
    void reset(Type* handle)
    if(handle_)
    sword result;
    if((result = OCIDescriptorFree(
    handle_,
    TypeId)) != OCI_SUCCESS)
    std::cerr << "Can't make OCIDescriptorFree" << std::endl;
    handle_ = handle;
    Type* get()
    return handle_;
    Type*& fill()
    reset(0);
    return handle_;
    private:
    Type* handle_;
    void throw_oci_error(
    const char* fun,
    const char* oci_op,
    long status,
    OCIError* oci_error_handler,
    const char* query = 0)
    std::cerr << fun << ": can't make " << oci_op << ": status = " << status;
    if(status == OCI_SUCCESS_WITH_INFO ||
    status == OCI_ERROR)
    std::cerr << ", message = '";
    text err_buf[1024] = "";
    sb4 err_code = 0;
    OCIErrorGet(
    oci_error_handler,
    (ub4)1,
    0,
    &err_code,
    err_buf,
    sizeof(err_buf),
    (ub4)OCI_HTYPE_ERROR);
    std::cerr << err_buf << "', error code = " << err_code;
    exit(1);
    if(query)
    std::cerr << ", sql = " << query;
    OCIHandlePtr<OCIEnv, OCI_HTYPE_ENV> environment_handle;
    void connect(
    OCIEnv* environment_handle,
    const char* db,
    const char* user,
    const char* password,
    OCIHandlePtr<OCIError, OCI_HTYPE_ERROR>& error_handle,
    OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER>& server_handle,
    OCIHandlePtr<OCISession, OCI_HTYPE_SESSION>& session_handle,
    OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX>& svc_context_handle)
    static const char* FUN = "connect()";
    sword result;
    // allocate an error handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **) &error_handle.fill(),
    OCI_HTYPE_ERROR,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // allocate a server handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **) &server_handle.fill(),
    OCI_HTYPE_SERVER,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    if((result = OCIServerAttach(
    server_handle.get(),
    error_handle.get(),
    (text*)db,
    strlen(db),
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIServerAttach", result, error_handle.get());
    // allocate a service handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **) &svc_context_handle.fill(),
    OCI_HTYPE_SVCCTX,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // set the server attribute in the service context handle
    if((result = OCIAttrSet(
    svc_context_handle.get(),
    OCI_HTYPE_SVCCTX,
    server_handle.get(),
    sizeof(OCIServer*),
    OCI_ATTR_SERVER,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // allocate a user session handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **)&session_handle.fill(),
    OCI_HTYPE_SESSION,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // set username and password attributes in user session handle
    if((result = OCIAttrSet(
    session_handle.get(),
    OCI_HTYPE_SESSION,
    (text*)user,
    strlen(user),
    OCI_ATTR_USERNAME,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    if((result = OCIAttrSet(
    session_handle.get(),
    OCI_HTYPE_SESSION,
    (text*)password,
    strlen(password),
    OCI_ATTR_PASSWORD,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    // start the session
    if((result = OCISessionBegin(
    svc_context_handle.get(),
    error_handle.get(),
    session_handle.get(),
    OCI_CRED_RDBMS,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCISessionBegin", result, error_handle.get());
    // set the user session attribute in the service context handle
    if((result = OCIAttrSet(
    svc_context_handle.get(),
    OCI_HTYPE_SVCCTX,
    session_handle.get(),
    sizeof(OCISession*),
    OCI_ATTR_SESSION,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    ub1 attr_value = 1;
    if((result = OCIAttrSet(
    server_handle.get(),
    OCI_HTYPE_SERVER,
    &attr_value,
    sizeof(attr_value),
    OCI_ATTR_NONBLOCKING_MODE,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    void disconnect(
    OCIEnv* environment_handle,
    OCIError* error_handle,
    OCIServer* server_handle,
    OCISession* session_handle,
    OCISvcCtx* svc_context_handle)
    static const char* FUN = "disconnect()";
    sword result;
    if((result = OCISessionEnd(
    svc_context_handle,
    error_handle,
    session_handle,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCISessionEnd", result, error_handle);
    if((result = OCIServerDetach(
    server_handle,
    error_handle,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIServerDetach", result, error_handle);
    OCILobLocator* FETCH_BUFFER_1[10000*1024];
    char IND_BUFFER_1[10000*1024];
    ub2 ERROR_BUFFER_1[1024];
    OCIDefine* define_handle_1;
    void clear_blob_buf(
    OCILobLocator** buf,
    unsigned long fetch_size)
    for(unsigned long i = 0; i < 1024; ++i)
    OCIDescriptorFree(
    buf,
    (ub4)OCI_DTYPE_LOB);
    ::memset(buf, 0, fetch_size * 1024);
    uint32_t RET_LEN4;
    sb4 oci_blob_callback(
    dvoid* ctx,
    OCIDefine* define,
    ub4 iter,
    dvoid** bufpp,
    ub4** alenpp,
    ub1* piecep,
    dvoid** indpp,
    ub2** rcodepp)
    RET_LEN4 = sizeof(OCILobLocator*);
    *bufpp = FETCH_BUFFER_1[iter];
    *alenpp = &RET_LEN4;
    *piecep = OCI_ONE_PIECE;
    *indpp = IND_BUFFER_1 + iter;
    *rcodepp = ERROR_BUFFER_1 + iter;
    //std::cout << "iter: " << iter << std::endl;
    return OCI_CONTINUE;
    int define_column(
    OCIEnv* environment_handle,
    OCISvcCtx* svc_handle,
    OCIStmt* stmt_handle,
    OCIError* error_handle,
    OCIDefine** define_handle,
    unsigned long pos,
    long oci_type,
    unsigned long fetch_size,
    OCILobLocator** buf,
    char* ind_buf,
    ub2* err_buf)
    static const char* FUN = "define_column()";
    sword result;
    if(oci_type == SQLT_BLOB)
    ::memset(buf, 0, fetch_size * 1024);
    for(int i = 0; i < 1024; ++i)
    if((result = OCIDescriptorAlloc(
    (dvoid*)environment_handle,
    (dvoid**)&buf[i],
    (ub4)OCI_DTYPE_LOB,
    (size_t)0,
    (dvoid**)0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIDescriptorAlloc", result, error_handle);
    ub2 size = 0;
    OCIDescriptorPtr<OCIParam, OCI_DTYPE_PARAM> param_handle;
    // ub2 oci_data_type = 0;
    if((result = OCIParamGet(
    stmt_handle,
    OCI_HTYPE_STMT,
    error_handle,
    reinterpret_cast<void**>(&param_handle.fill()),
    pos)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIParamGet", result, error_handle);
    if((result = OCIAttrGet(
    param_handle.get(),
    OCI_DTYPE_PARAM,
    &size,
    0,
    OCI_ATTR_DATA_SIZE,
    error_handle)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrGet", result, error_handle);
    if((result = OCIDefineByPos(
    stmt_handle,
    define_handle,
    error_handle,
    pos,
    # ifdef _DYN
    0,
    -1,
    #else
    buf,
    fetch_size,
    #endif
    oci_type,
    ind_buf,
    0,
    err_buf, // ptr to array of column-level return codes
    # ifdef _DYN
    OCI_DYNAMIC_FETCH
    # else
    OCI_DEFAULT
    # endif
    )) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
    # ifdef _DYN
    if((result = OCIDefineDynamic(
    *define_handle,
    error_handle,
    0,
    oci_blob_callback)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
    # endif
    return 0;
    int define_columns(
    OCIEnv* environment_handle,
    OCISvcCtx* svc_handle,
    OCIStmt* stmt_handle,
    OCIError* error_handle)
    static const char* FUN = "define_columns()";
    define_handle_1 = 0;
    int pos = 1;
    ::memset(ERROR_BUFFER_1, 0, 1024 * sizeof(ERROR_BUFFER_1[0]));
    define_column(
    environment_handle,
    svc_handle,
    stmt_handle,
    error_handle,
    &define_handle_1,
    pos++,
    SQLT_BLOB,
    sizeof(OCILobLocator*),
    FETCH_BUFFER_1,
    IND_BUFFER_1,
    ERROR_BUFFER_1);
    return 0;
    int execute_select(
    const char* db,
    const char* user,
    const char* password)
    static const char* FUN = "execute_select()";
    const unsigned long FETCH_COUNT = 1024;
    OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
    OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
    OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
    OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
    connect(
    environment_handle.get(),
    db,
    user,
    password,
    error_handle,
    server_handle,
    session_handle,
    svc_context_handle);
    OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
    sword result;
    if((result = OCIHandleAlloc(
    environment_handle.get(),
    (void**)&stmt_handle.fill(),
    OCI_HTYPE_STMT,
    0,
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    const char QUERY[] = "SELECT text FROM ADSERVERTEST_BLOB";
    ub4 rows = 0;
    if((result = OCIAttrSet(
    stmt_handle.get(),
    OCI_HTYPE_STMT,
    (dvoid *)&rows,
    (ub4)sizeof(ub4),
    OCI_ATTR_PREFETCH_ROWS,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(
    FUN, "OCIAttrSet(OCI_ATTR_PREFETCH_ROWS)", result, error_handle.get());
    if((result = OCIStmtPrepare(
    stmt_handle.get(),
    error_handle.get(),
    (text*)QUERY,
    strlen(QUERY),
    OCI_NTV_SYNTAX,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
    ub2 stmt_type;
    if((result = OCIAttrGet(
    stmt_handle.get(),
    OCI_HTYPE_STMT,
    &stmt_type,
    0,
    OCI_ATTR_STMT_TYPE,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
    ub4 prev_fetched = 0;
    while((result = OCIStmtExecute(
    svc_context_handle.get(),
    stmt_handle.get(),
    error_handle.get(),
    0,
    0,
    0,
    0,
    OCI_DEFAULT)) != OCI_SUCCESS)
    if(result != OCI_STILL_EXECUTING)
    throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
    define_columns(
    environment_handle.get(),
    svc_context_handle.get(),
    stmt_handle.get(),
    error_handle.get());
    ub4 all_fetched_count = 0;
    while(true)
    while((result = OCIStmtFetch2(
    stmt_handle.get(),
    error_handle.get(),
    FETCH_COUNT,
    OCI_FETCH_NEXT,
    1,
    OCI_DEFAULT)) == OCI_STILL_EXECUTING
    # ifdef _DYN
    // || result == OCI_NEED_DATA
    # endif
    if (result != OCI_SUCCESS &&
    result != OCI_NO_DATA &&
    result != OCI_SUCCESS_WITH_INFO)
    std::cerr << FUN << ": can't make OCIStmtFetch2: status = " << result;
    std::cerr << ", message = '";
    text err_buf[1024] = "";
    sb4 err_code = 0;
    OCIErrorGet(
    error_handle.get(),
    (ub4)1,
    0,
    &err_code,
    err_buf,
    sizeof(err_buf),
    (ub4)OCI_HTYPE_ERROR);
    std::cerr << err_buf << "', error code = " << err_code << ", row errors: ";
    for(const ub2* cur = ERROR_BUFFER_1;
    cur < ERROR_BUFFER_1 + 1024; ++cur)
    if(*cur)
    std::cerr << "#" << (cur - ERROR_BUFFER_1) << ": " <<
    *cur << std::endl;
    ub4 fetched_count = 0;
    if((result = OCIAttrGet (
    stmt_handle.get(),
    OCI_HTYPE_STMT,
    &fetched_count,
    0,
    OCI_ATTR_ROW_COUNT,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
    all_fetched_count += fetched_count;
    if(fetched_count > 0)
    for(unsigned long i = 0; i < fetched_count - 1; ++i)
    ub4 lob_size;
    while((result = OCILobGetLength(
    svc_context_handle.get(),
    error_handle.get(),
    FETCH_BUFFER_1[i],
    &lob_size)) == OCI_STILL_EXECUTING)
    if(result != OCI_SUCCESS)
    throw_oci_error(FUN, "OCILobGetLength", result, error_handle.get());
    std::cout << "#" << i << ": ind = " << (unsigned long)IND_BUFFER_1[i] <<
    ", len = " << lob_size << std::endl;
    if(fetched_count - prev_fetched < FETCH_COUNT)
    break;
    prev_fetched = fetched_count;
    clear_blob_buf(
    FETCH_BUFFER_1,
    sizeof(OCILobLocator*));
    while((result = OCIStmtFetch(
    stmt_handle.get(),
    error_handle.get(),
    0,
    OCI_FETCH_NEXT,
    OCI_DEFAULT)) == OCI_STILL_EXECUTING
    disconnect(
    environment_handle.get(),
    error_handle.get(),
    server_handle.get(),
    session_handle.get(),
    svc_context_handle.get());
    return 0;
    int execute_update(
    const char* db,
    const char* user,
    const char* password)
    static const char* FUN = "execute_update()";
    OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
    OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
    OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
    OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
    connect(
    environment_handle.get(),
    db,
    user,
    password,
    error_handle,
    server_handle,
    session_handle,
    svc_context_handle);
    OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
    for(int i = 0; i < 1000; ++i)
    sword result;
    if((result = OCIHandleAlloc(
    environment_handle.get(),
    (void**)&stmt_handle.fill(),
    OCI_HTYPE_STMT,
    0,
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    std::ostringstream sql;
    std::string str;
    std::string et("\xEB\xB2\x88");
    unsigned long rep = ::rand() % 500 + 1;
    str.reserve(rep*et.size());
    for(unsigned long ei = 0; ei < rep; ++ei)
    str.append(et);
    sql << "BEGIN " <<
    "UPDATE ADSERVERTEST_BLOB SET text = "
    "utl_raw.cast_to_raw('" << str << "') "
    "WHERE id = " << i <<
    "END;";
    if((result = OCIStmtPrepare(
    stmt_handle.get(),
    error_handle.get(),
    (text*)sql.str().c_str(),
    sql.str().length(),
    OCI_NTV_SYNTAX,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
    while((result = OCIStmtExecute(
    svc_context_handle.get(),
    stmt_handle.get(),
    error_handle.get(),
    1,
    0,
    0,
    0,
    OCI_DEFAULT)) != OCI_SUCCESS)
    if(result != OCI_STILL_EXECUTING)
    throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
    disconnect(
    environment_handle.get(),
    error_handle.get(),
    server_handle.get(),
    session_handle.get(),
    svc_context_handle.get());
    return 0;
    void* select_thread(void* ctx)
    while(true)
    execute_select(
    "//oraclept.ocslab.com/addbpt.ocslab.com",
    "bs_unittest_4",
    "adserver");
    // std::cout << "select finished" << std::endl;
    return ctx;
    void* update_thread(void* ctx)
    while(true)
    execute_update(
    "//oraclept.ocslab.com/addbpt.ocslab.com",
    "bs_unittest_4",
    "adserver");
    // std::cout << "update finished" << std::endl;
    return ctx;
    int main()
    static const char* FUN = "main()";
    sword result;
    // allocate an environment handle
    if((result = OCIEnvCreate(
    &environment_handle.fill(),
    OCI_OBJECT | OCI_THREADED,
    0, // context
    0, // malloc
    0, // realloc
    0, // free
    0, // extra memory to allocate
    0) // pointer to user-memory
    ) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIEnvCreate", result, 0);
    pthread_t th1, th2;
    pthread_create(&th1, 0, select_thread, 0);
    pthread_create(&th2, 0, update_thread, 0);
    pthread_join(th1, 0);
    pthread_join(th2, 0);
    return 0;
    Edited by: user13011391 on 20.04.2010 5:50
    Edited by: user13011391 on 20.04.2010 6:00
    Edited by: user13011391 on 20.04.2010 6:15

    Hi all.
    I have problem:
    I try select BLOB field into OCILobLocator* buffer in Non Blocking mode, and receive 'ORA-03106: fatal two-task communication protocol error' sometimes.
    Details:
    Application contains two threads : 1. select blob field, 2. update it.
    I tried separate update and select to different apps (and run its in one time) - problem reproduced.
    problem reproduced for OCIStmtFetch and OCIStmtFetch2.
    If disable non blocking mode - problem disappear.
    if error appear - record level error code contains 1405. Need wait few minutes for error message appearing (~1 minute in my case).
    Using of OCI_DEFAULT in OCIDefineByPos instead OCI_DYNAMIC_FETCH don't solve problem.
    I use oracle server and client library with version 10.2.0.4
    Output sample:
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #877: 1405
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #54: 1405
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #877: 1405
    execute_select(): can't make OCIStmtFetch2: status = -1, message = 'ORA-03106: fatal two-task communication protocol error
    ', error code = 3106, row errors: #54: 1405
    Can anybody help me ?
    m.b. exists workaround ?
    #include <iostream>
    #include <sstream>
    #include <assert.h>
    #include <oci.h>
    #define _DYN 1
    before run this test run next sql at DB:
    CREATE TABLE ADSERVERTEST_BLOB(id NUMBER(10), text BLOB);
    BEGIN
    FOR i IN 0..999 LOOP
    INSERT INTO ADSERVERTEST_BLOB(id, text) VALUES(i, utl_raw.cast_to_raw('init'));
    END LOOP;
    END;
    template<typename Type, unsigned long TypeId>
    class OCIHandlePtr
    public:
    OCIHandlePtr(): handle_(0) {}
    OCIHandlePtr(Type* handle): handle_(handle) {}
    ~OCIHandlePtr()
    reset(0);
    void reset(Type* handle)
    if(handle_)
    sword result;
    if((result = OCIHandleFree(
    handle_,
    TypeId)) != OCI_SUCCESS)
    assert(0);
    std::cerr << "Can't make OCIHandleFree" << std::endl;
    handle_ = handle;
    Type* get()
    return handle_;
    Type*& fill()
    reset(0);
    return handle_;
    private:
    Type* handle_;
    template<typename Type, unsigned long TypeId>
    class OCIDescriptorPtr
    public:
    OCIDescriptorPtr(): handle_(0) {}
    OCIDescriptorPtr(Type* handle): handle_(handle) {}
    ~OCIDescriptorPtr()
    reset(0);
    void reset(Type* handle)
    if(handle_)
    sword result;
    if((result = OCIDescriptorFree(
    handle_,
    TypeId)) != OCI_SUCCESS)
    std::cerr << "Can't make OCIDescriptorFree" << std::endl;
    handle_ = handle;
    Type* get()
    return handle_;
    Type*& fill()
    reset(0);
    return handle_;
    private:
    Type* handle_;
    void throw_oci_error(
    const char* fun,
    const char* oci_op,
    long status,
    OCIError* oci_error_handler,
    const char* query = 0)
    std::cerr << fun << ": can't make " << oci_op << ": status = " << status;
    if(status == OCI_SUCCESS_WITH_INFO ||
    status == OCI_ERROR)
    std::cerr << ", message = '";
    text err_buf[1024] = "";
    sb4 err_code = 0;
    OCIErrorGet(
    oci_error_handler,
    (ub4)1,
    0,
    &err_code,
    err_buf,
    sizeof(err_buf),
    (ub4)OCI_HTYPE_ERROR);
    std::cerr << err_buf << "', error code = " << err_code;
    exit(1);
    if(query)
    std::cerr << ", sql = " << query;
    OCIHandlePtr<OCIEnv, OCI_HTYPE_ENV> environment_handle;
    void connect(
    OCIEnv* environment_handle,
    const char* db,
    const char* user,
    const char* password,
    OCIHandlePtr<OCIError, OCI_HTYPE_ERROR>& error_handle,
    OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER>& server_handle,
    OCIHandlePtr<OCISession, OCI_HTYPE_SESSION>& session_handle,
    OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX>& svc_context_handle)
    static const char* FUN = "connect()";
    sword result;
    // allocate an error handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **) &error_handle.fill(),
    OCI_HTYPE_ERROR,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // allocate a server handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **) &server_handle.fill(),
    OCI_HTYPE_SERVER,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    if((result = OCIServerAttach(
    server_handle.get(),
    error_handle.get(),
    (text*)db,
    strlen(db),
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIServerAttach", result, error_handle.get());
    // allocate a service handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **) &svc_context_handle.fill(),
    OCI_HTYPE_SVCCTX,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // set the server attribute in the service context handle
    if((result = OCIAttrSet(
    svc_context_handle.get(),
    OCI_HTYPE_SVCCTX,
    server_handle.get(),
    sizeof(OCIServer*),
    OCI_ATTR_SERVER,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // allocate a user session handle
    if((result = OCIHandleAlloc(
    environment_handle,
    (void **)&session_handle.fill(),
    OCI_HTYPE_SESSION,
    0, // extra memory to allocate
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    // set username and password attributes in user session handle
    if((result = OCIAttrSet(
    session_handle.get(),
    OCI_HTYPE_SESSION,
    (text*)user,
    strlen(user),
    OCI_ATTR_USERNAME,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    if((result = OCIAttrSet(
    session_handle.get(),
    OCI_HTYPE_SESSION,
    (text*)password,
    strlen(password),
    OCI_ATTR_PASSWORD,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    // start the session
    if((result = OCISessionBegin(
    svc_context_handle.get(),
    error_handle.get(),
    session_handle.get(),
    OCI_CRED_RDBMS,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCISessionBegin", result, error_handle.get());
    // set the user session attribute in the service context handle
    if((result = OCIAttrSet(
    svc_context_handle.get(),
    OCI_HTYPE_SVCCTX,
    session_handle.get(),
    sizeof(OCISession*),
    OCI_ATTR_SESSION,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    ub1 attr_value = 1;
    if((result = OCIAttrSet(
    server_handle.get(),
    OCI_HTYPE_SERVER,
    &attr_value,
    sizeof(attr_value),
    OCI_ATTR_NONBLOCKING_MODE,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrSet", result, error_handle.get());
    void disconnect(
    OCIEnv* environment_handle,
    OCIError* error_handle,
    OCIServer* server_handle,
    OCISession* session_handle,
    OCISvcCtx* svc_context_handle)
    static const char* FUN = "disconnect()";
    sword result;
    if((result = OCISessionEnd(
    svc_context_handle,
    error_handle,
    session_handle,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCISessionEnd", result, error_handle);
    if((result = OCIServerDetach(
    server_handle,
    error_handle,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIServerDetach", result, error_handle);
    OCILobLocator* FETCH_BUFFER_1[10000*1024];
    char IND_BUFFER_1[10000*1024];
    ub2 ERROR_BUFFER_1[1024];
    OCIDefine* define_handle_1;
    void clear_blob_buf(
    OCILobLocator** buf,
    unsigned long fetch_size)
    for(unsigned long i = 0; i < 1024; ++i)
    OCIDescriptorFree(
    buf,
    (ub4)OCI_DTYPE_LOB);
    ::memset(buf, 0, fetch_size * 1024);
    uint32_t RET_LEN4;
    sb4 oci_blob_callback(
    dvoid* ctx,
    OCIDefine* define,
    ub4 iter,
    dvoid** bufpp,
    ub4** alenpp,
    ub1* piecep,
    dvoid** indpp,
    ub2** rcodepp)
    RET_LEN4 = sizeof(OCILobLocator*);
    *bufpp = FETCH_BUFFER_1[iter];
    *alenpp = &RET_LEN4;
    *piecep = OCI_ONE_PIECE;
    *indpp = IND_BUFFER_1 + iter;
    *rcodepp = ERROR_BUFFER_1 + iter;
    //std::cout << "iter: " << iter << std::endl;
    return OCI_CONTINUE;
    int define_column(
    OCIEnv* environment_handle,
    OCISvcCtx* svc_handle,
    OCIStmt* stmt_handle,
    OCIError* error_handle,
    OCIDefine** define_handle,
    unsigned long pos,
    long oci_type,
    unsigned long fetch_size,
    OCILobLocator** buf,
    char* ind_buf,
    ub2* err_buf)
    static const char* FUN = "define_column()";
    sword result;
    if(oci_type == SQLT_BLOB)
    ::memset(buf, 0, fetch_size * 1024);
    for(int i = 0; i < 1024; ++i)
    if((result = OCIDescriptorAlloc(
    (dvoid*)environment_handle,
    (dvoid**)&buf[i],
    (ub4)OCI_DTYPE_LOB,
    (size_t)0,
    (dvoid**)0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIDescriptorAlloc", result, error_handle);
    ub2 size = 0;
    OCIDescriptorPtr<OCIParam, OCI_DTYPE_PARAM> param_handle;
    // ub2 oci_data_type = 0;
    if((result = OCIParamGet(
    stmt_handle,
    OCI_HTYPE_STMT,
    error_handle,
    reinterpret_cast<void**>(&param_handle.fill()),
    pos)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIParamGet", result, error_handle);
    if((result = OCIAttrGet(
    param_handle.get(),
    OCI_DTYPE_PARAM,
    &size,
    0,
    OCI_ATTR_DATA_SIZE,
    error_handle)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrGet", result, error_handle);
    if((result = OCIDefineByPos(
    stmt_handle,
    define_handle,
    error_handle,
    pos,
    # ifdef _DYN
    0,
    -1,
    #else
    buf,
    fetch_size,
    #endif
    oci_type,
    ind_buf,
    0,
    err_buf, // ptr to array of column-level return codes
    # ifdef _DYN
    OCI_DYNAMIC_FETCH
    # else
    OCI_DEFAULT
    # endif
    )) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
    # ifdef _DYN
    if((result = OCIDefineDynamic(
    *define_handle,
    error_handle,
    0,
    oci_blob_callback)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIDefineByPos", result, error_handle);
    # endif
    return 0;
    int define_columns(
    OCIEnv* environment_handle,
    OCISvcCtx* svc_handle,
    OCIStmt* stmt_handle,
    OCIError* error_handle)
    static const char* FUN = "define_columns()";
    define_handle_1 = 0;
    int pos = 1;
    ::memset(ERROR_BUFFER_1, 0, 1024 * sizeof(ERROR_BUFFER_1[0]));
    define_column(
    environment_handle,
    svc_handle,
    stmt_handle,
    error_handle,
    &define_handle_1,
    pos++,
    SQLT_BLOB,
    sizeof(OCILobLocator*),
    FETCH_BUFFER_1,
    IND_BUFFER_1,
    ERROR_BUFFER_1);
    return 0;
    int execute_select(
    const char* db,
    const char* user,
    const char* password)
    static const char* FUN = "execute_select()";
    const unsigned long FETCH_COUNT = 1024;
    OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
    OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
    OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
    OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
    connect(
    environment_handle.get(),
    db,
    user,
    password,
    error_handle,
    server_handle,
    session_handle,
    svc_context_handle);
    OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
    sword result;
    if((result = OCIHandleAlloc(
    environment_handle.get(),
    (void**)&stmt_handle.fill(),
    OCI_HTYPE_STMT,
    0,
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    const char QUERY[] = "SELECT text FROM ADSERVERTEST_BLOB";
    ub4 rows = 0;
    if((result = OCIAttrSet(
    stmt_handle.get(),
    OCI_HTYPE_STMT,
    (dvoid *)&rows,
    (ub4)sizeof(ub4),
    OCI_ATTR_PREFETCH_ROWS,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(
    FUN, "OCIAttrSet(OCI_ATTR_PREFETCH_ROWS)", result, error_handle.get());
    if((result = OCIStmtPrepare(
    stmt_handle.get(),
    error_handle.get(),
    (text*)QUERY,
    strlen(QUERY),
    OCI_NTV_SYNTAX,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
    ub2 stmt_type;
    if((result = OCIAttrGet(
    stmt_handle.get(),
    OCI_HTYPE_STMT,
    &stmt_type,
    0,
    OCI_ATTR_STMT_TYPE,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
    ub4 prev_fetched = 0;
    while((result = OCIStmtExecute(
    svc_context_handle.get(),
    stmt_handle.get(),
    error_handle.get(),
    0,
    0,
    0,
    0,
    OCI_DEFAULT)) != OCI_SUCCESS)
    if(result != OCI_STILL_EXECUTING)
    throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
    define_columns(
    environment_handle.get(),
    svc_context_handle.get(),
    stmt_handle.get(),
    error_handle.get());
    ub4 all_fetched_count = 0;
    while(true)
    while((result = OCIStmtFetch2(
    stmt_handle.get(),
    error_handle.get(),
    FETCH_COUNT,
    OCI_FETCH_NEXT,
    1,
    OCI_DEFAULT)) == OCI_STILL_EXECUTING
    # ifdef _DYN
    // || result == OCI_NEED_DATA
    # endif
    if (result != OCI_SUCCESS &&
    result != OCI_NO_DATA &&
    result != OCI_SUCCESS_WITH_INFO)
    std::cerr << FUN << ": can't make OCIStmtFetch2: status = " << result;
    std::cerr << ", message = '";
    text err_buf[1024] = "";
    sb4 err_code = 0;
    OCIErrorGet(
    error_handle.get(),
    (ub4)1,
    0,
    &err_code,
    err_buf,
    sizeof(err_buf),
    (ub4)OCI_HTYPE_ERROR);
    std::cerr << err_buf << "', error code = " << err_code << ", row errors: ";
    for(const ub2* cur = ERROR_BUFFER_1;
    cur < ERROR_BUFFER_1 + 1024; ++cur)
    if(*cur)
    std::cerr << "#" << (cur - ERROR_BUFFER_1) << ": " <<
    *cur << std::endl;
    ub4 fetched_count = 0;
    if((result = OCIAttrGet (
    stmt_handle.get(),
    OCI_HTYPE_STMT,
    &fetched_count,
    0,
    OCI_ATTR_ROW_COUNT,
    error_handle.get())) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIAttrGet", result, error_handle.get());
    all_fetched_count += fetched_count;
    if(fetched_count > 0)
    for(unsigned long i = 0; i < fetched_count - 1; ++i)
    ub4 lob_size;
    while((result = OCILobGetLength(
    svc_context_handle.get(),
    error_handle.get(),
    FETCH_BUFFER_1[i],
    &lob_size)) == OCI_STILL_EXECUTING)
    if(result != OCI_SUCCESS)
    throw_oci_error(FUN, "OCILobGetLength", result, error_handle.get());
    std::cout << "#" << i << ": ind = " << (unsigned long)IND_BUFFER_1[i] <<
    ", len = " << lob_size << std::endl;
    if(fetched_count - prev_fetched < FETCH_COUNT)
    break;
    prev_fetched = fetched_count;
    clear_blob_buf(
    FETCH_BUFFER_1,
    sizeof(OCILobLocator*));
    while((result = OCIStmtFetch(
    stmt_handle.get(),
    error_handle.get(),
    0,
    OCI_FETCH_NEXT,
    OCI_DEFAULT)) == OCI_STILL_EXECUTING
    disconnect(
    environment_handle.get(),
    error_handle.get(),
    server_handle.get(),
    session_handle.get(),
    svc_context_handle.get());
    return 0;
    int execute_update(
    const char* db,
    const char* user,
    const char* password)
    static const char* FUN = "execute_update()";
    OCIHandlePtr<OCIError, OCI_HTYPE_ERROR> error_handle;
    OCIHandlePtr<OCIServer, OCI_HTYPE_SERVER> server_handle;
    OCIHandlePtr<OCISession, OCI_HTYPE_SESSION> session_handle;
    OCIHandlePtr<OCISvcCtx, OCI_HTYPE_SVCCTX> svc_context_handle;
    connect(
    environment_handle.get(),
    db,
    user,
    password,
    error_handle,
    server_handle,
    session_handle,
    svc_context_handle);
    OCIHandlePtr<OCIStmt, OCI_HTYPE_STMT> stmt_handle;
    for(int i = 0; i < 1000; ++i)
    sword result;
    if((result = OCIHandleAlloc(
    environment_handle.get(),
    (void**)&stmt_handle.fill(),
    OCI_HTYPE_STMT,
    0,
    0)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIHandleAlloc", result, error_handle.get());
    std::ostringstream sql;
    std::string str;
    std::string et("\xEB\xB2\x88");
    unsigned long rep = ::rand() % 500 + 1;
    str.reserve(rep*et.size());
    for(unsigned long ei = 0; ei < rep; ++ei)
    str.append(et);
    sql << "BEGIN " <<
    "UPDATE ADSERVERTEST_BLOB SET text = "
    "utl_raw.cast_to_raw('" << str << "') "
    "WHERE id = " << i <<
    "END;";
    if((result = OCIStmtPrepare(
    stmt_handle.get(),
    error_handle.get(),
    (text*)sql.str().c_str(),
    sql.str().length(),
    OCI_NTV_SYNTAX,
    OCI_DEFAULT)) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIStmtPrepare", result, error_handle.get());
    while((result = OCIStmtExecute(
    svc_context_handle.get(),
    stmt_handle.get(),
    error_handle.get(),
    1,
    0,
    0,
    0,
    OCI_DEFAULT)) != OCI_SUCCESS)
    if(result != OCI_STILL_EXECUTING)
    throw_oci_error(FUN, "OCIStmtExecute", result, error_handle.get());
    disconnect(
    environment_handle.get(),
    error_handle.get(),
    server_handle.get(),
    session_handle.get(),
    svc_context_handle.get());
    return 0;
    void* select_thread(void* ctx)
    while(true)
    execute_select(
    "//oraclept.ocslab.com/addbpt.ocslab.com",
    "bs_unittest_4",
    "adserver");
    // std::cout << "select finished" << std::endl;
    return ctx;
    void* update_thread(void* ctx)
    while(true)
    execute_update(
    "//oraclept.ocslab.com/addbpt.ocslab.com",
    "bs_unittest_4",
    "adserver");
    // std::cout << "update finished" << std::endl;
    return ctx;
    int main()
    static const char* FUN = "main()";
    sword result;
    // allocate an environment handle
    if((result = OCIEnvCreate(
    &environment_handle.fill(),
    OCI_OBJECT | OCI_THREADED,
    0, // context
    0, // malloc
    0, // realloc
    0, // free
    0, // extra memory to allocate
    0) // pointer to user-memory
    ) != OCI_SUCCESS)
    throw_oci_error(FUN, "OCIEnvCreate", result, 0);
    pthread_t th1, th2;
    pthread_create(&th1, 0, select_thread, 0);
    pthread_create(&th2, 0, update_thread, 0);
    pthread_join(th1, 0);
    pthread_join(th2, 0);
    return 0;
    Edited by: user13011391 on 20.04.2010 5:50
    Edited by: user13011391 on 20.04.2010 6:00
    Edited by: user13011391 on 20.04.2010 6:15

  • Broken Pipe with Non-blocking Socket

    Hello,
    I write a Unix Agent who connect on a Windows Server with socket...
    Working well on Linux but on Solaris my problem is:
    -When my agent is running before server at connection all seems OK: Connect, Select and Getsockopt but when I try to send data I have always EPIPE Signal but I can receive datas from server !
    - When my agent is strarting after the server all it's Ok
    I don't unserstand this appears on Solaris SPARC 8 and Solaris 9 Intel ...
    Please Help is there something special with non-blocking sockets on Solaris ?
    Thanks

    Can't help you much but what I would recommend is that you
    insure that your pipes are opened for both read/write, even
    though you are only going to read or write from it. This insures
    that the pipe does not close down when you hit EOF.

  • Non blocking sockets

    Hi All,
    Anybody have some idea about how to implement non blocking sockets using two threads/Can u help me with some sites where i can get more information in this topic.
    Regards
    Priya

    hi,
    you could have a look at the nonblocking io (nio) api's present in jdk1.4, that should do the trick. this link ought to get u started i suppose..
    http://developer.java.sun.com/developer/technicalArticles/releases/nio/
    hope this helps.
    cheerz
    ynkrish

  • Read Timeout on non-blocking sockets

    Hi,
    I was wondering if there is a way to specify a read timeout (like setSoTimeout for synchronous sockets) when using a non-blocking socket.
    I'd like to have the select() method return is a sockets timeout expires, puting in the selected key set the timedout socket and have it's read operation return -1, something like what happens when a socket is closed by the other side.
    The thing is I need this to be a timeout specific to each socket, thus the select(millis) isn't apropriate.
    Anyone knows of something like this?
    Thanks....

    Yeah, select() is the only thing built in for that, and you have to do the bookkeeping yourself. You would start something like forming the disjunction of the ready keys and the registered keys after each select, to get the unready keys, and then looking at their history to see how long they have been unready via a Map{key,Long(time)).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Using non blocking connect() call for SCTP sockets in Solaris10

    Hi,
    I have a problem with non blocking connect call on SCTP socket.
    I am using the sctp stack support in Solaris10.
    When the connect is successful, I can get the pollout event on the socket.
    But there is no event observed when the peer does not exist. In other words, I could not get the pollout event on connection failure. This logic works fine with TCP sockets on both Solaris and Suse10.
    I am working with SCTP one-to-one style sockets.
    Is there any way to handle this issue?
    Do I need to load any patch to resolve this issue?
    It will be great if I get a solution in this regard.
    Thanks in advance.
    Best Regards,
    Bipin.

    There are at least two problems here.
    A. In the receiver you should test for -1 from the read() immediately, rather than continue with the loop and try to write -1 bytes to the file.
    B. In the sender you are ignoring the return value of client.write(), which can be anything from 0 to the buffer length. If you get 0 you should wait for another OP_WRITE to trigger; if you get a 'short write' you need to retry it until you've got nothing left to write from the current buffer, before you read any more data. This is where the data is vanishing.

Maybe you are looking for