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.

Similar Messages

  • FileChannel.transferTo() using non-blocking SocketChannel

    I'm looking to use FileChannel.transfer(From/To) for performing file transfers over a network. On the uploading side I find that even though I set the SocketChannel to non-blocking mode, the loop manages to send files as large as 30MB in only a single transferTo() invocation. What I'm hoping for is to have a series of partial writes so that I might generate progress notifications, which does occur on the downloading side with transferFrom(). I don't think a file that large should be transferred in one pass so I'm thinking that this is caused by either some internal buffer allocation issue or a goof-up on my part.
    Thanks in advance for any input and here's the uploading code:
    public void upload( String fileName ) {
    FileInputStream fileStrm = null;
    FileChannel fileChan = null;
    FileLock fileLock = null;
    SocketChannel sockChan = null;
    Selector selector = null;
    try {
    // Lock the source file.
    file = new File( fileName );
    fileStrm = new FileInputStream( file );
    fileChan = fileStrm.getChannel();
    fileLock = fileChan.lock( 0L, Long.MAX_VALUE, true );
    // Open a server socket bound to an arbitrary port.
    servChan = ServerSocketChannel.open();
    servChan.socket().bind( new InetSocketAddress( 0 ) );
    // Wait for a single connection and close the server socket.
    sockChan = servChan.accept();
    servChan.close();
    sockChan.configureBlocking( false );
    selector = Selector.open();
    SelectionKey selectorKey = sockChan.register( selector, SelectionKey.OP_WRITE );
    // Loop until transfer has completed.
    int fileSize = ( int ) file.length();
    int sizeLeft = fileSize;
    while ( sizeLeft > 0 ) {
    // Wait for data to read, then transfer it.
    if ( selector.select() == 1 && selectorKey.isWritable() ) {
    sizeLeft -= ( int ) fileChan.transferTo( fileSize - sizeLeft, sizeLeft, sockChan );
    // Generate a progress notification here such as:
    // monitor.bytesTransferred( fileSize - sizeLeft );
    catch ( IOException ex ) {
    ex.printStackTrace();
    finally {
    try {
    // Cleanup.
    if ( selector != null )
    selector.close();
    if ( sockChan != null )
    sockChan.close();
    if ( fileLock != null )
    fileLock.release();
    if ( fileChan != null )
    fileChan.close();
    if ( fileStrm != null )
    fileStrm.close();
    catch ( IOException ex ) {
    ex.printStackTrace();
    -Edwin

    Actually, the sending process appears way ahead of the receiving one, where the send seems to finish in a blink while the receive takes several seconds to complete. In other words, the transferTo() completes in one loop, while the transferFrom() performs many with delays in between. I'd guess all that data is sitting in some large outbound buffer at the sender, which would explain why it seems to finish too quickly. If I split the send into smaller chunks, the two sides run quite nearly at the same pace as expected.
    The receiver already sleeps by way of a select() against a non-blocking SocketChannel, so I'll try reducing the buffer sizes as you suggest.

  • Are the experts wrong about non-blocking SocketChannels?

    Everyone says to use the new SocketChannel and Selector for "highly scalable" server applications. So I ran a couple of tests using non-blocking (via Selector) and thread-per-connection SocketChannels.
    The Selector version consumes 8x more cpu than the thread-per-connecton version!
    Using JDK 1.4.1 FCS on Win2K, with 1000 socket connections each sending 1k bytes per second, the Selector version was consuming 40% cpu with 10 threads; the thread-per-connection version (using blocking SocketChannels) was only consuming about 5% cpu with 1009 threads.
    So, are the experts wrong? Is there a performance problem when number of SocketChannels exceed a certain threshold?
    For anyone interested, here's the source code:
    Non-Blocking Server using Selector
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.nio.charset.CharsetEncoder;
    import java.nio.channels.FileChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    public class Server4 implements Runnable
    private static int port = 80;
    public static void main(String args[]) throws Exception
    Server4 server = new Server4();
    Thread thread = new Thread(server);
    thread.setDaemon(true);
    thread.start();
    thread.join();
    public Server4() throws IOException
    ServerSocketChannel server = ServerSocketChannel.open();
    InetSocketAddress isa = new InetSocketAddress(port);
    server.configureBlocking(false);
    server.socket().bind(isa);
    m_selector = Selector.open();
    server.register(m_selector, SelectionKey.OP_ACCEPT);
    Charset utf8 = Charset.forName("UTF-8");
    m_decoder = utf8.newDecoder();
    m_encoder = utf8.newEncoder();
    public void run()
    int count = 0;
    try
    ByteBuffer buffer = ByteBuffer.allocateDirect(2048);
    //FileOutputStream fos = new FileOutputStream("server4.dat");
    //FileChannel fc = fos.getChannel();
    while (m_selector.select() > 0)
    Set keys = m_selector.selectedKeys();
    for (Iterator itr = keys.iterator(); itr.hasNext(); )
    SelectionKey key = (SelectionKey) itr.next();
    itr.remove();
    if (key.isAcceptable())
    System.out.println("accept: " + (++count));
    ServerSocketChannel server
    = (ServerSocketChannel) key.channel();
    SocketChannel channel = server.accept();
    channel.configureBlocking(false);
    channel.register(m_selector, SelectionKey.OP_READ);
    else
    SocketChannel channel = null;
    try
    if (key.isReadable())
    channel = (SocketChannel) key.channel();
    int bytes = channel.read(buffer);
    if (bytes <= 0) // Linux does not throw IOException
    channel.close(); // will also cancel key
    System.out.println("connection closed " + count);
    else
    buffer.flip();
    //fc.write(buffer);
    buffer.clear();
    catch (IOException ioe) // connection closed by client
    System.out.println("readable: " + ioe.getMessage());
    sm_logger.log(Level.INFO, ioe.getMessage(), ioe);
    Throwable cause = ioe.getCause();
    if (cause != null)
    System.out.println("cause: "
    + cause.getClass().getName()
    + ": " + cause.getMessage());
    channel.close(); // will also cancel key
    --count;
    catch (IOException e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    catch (Exception e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    private Selector m_selector;
    private CharsetDecoder m_decoder;
    private CharsetEncoder m_encoder;
    private static Logger sm_logger = Logger.getLogger("Server");
    Thread-Per-Connection Server
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.nio.charset.CharsetEncoder;
    import java.nio.channels.FileChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    public class MultiThreadServer implements Runnable
    private static int port = 80;
    public static void main(String[] args) throws Exception
    ServerSocketChannel server = ServerSocketChannel.open();
    InetSocketAddress isa = new InetSocketAddress(port);
    server.socket().bind(isa);
    int count = 0;
    while (true)
    SocketChannel channel = server.accept();
    System.out.println("accept: " + (++count));
    MultiThreadServer worker = new MultiThreadServer(channel);
    Thread thread = new Thread(worker);
    thread.setDaemon(true);
    thread.start();
    public MultiThreadServer(SocketChannel channel) throws IOException
    m_channel = channel;
    public void run()
    ByteBuffer buffer = ByteBuffer.allocateDirect(2048);
    int bytes = 0;
    try
    while ((bytes = m_channel.read(buffer)) > 0)
    buffer.flip();
    // process buffer
    buffer.clear();
    System.out.println("connection closed");
    m_channel.close();
    catch (IOException e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    catch (Exception e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    private SocketChannel m_channel;
    private static Logger sm_logger = Logger.getLogger("MultiThreadServer");
    Client
    import java.io.*;
    import java.net.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.charset.*;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    public class MultiClient implements Runnable
    public static void main(String[] args) throws Exception
    if (args.length < 1)
    System.out.println("usage: java MultiClient number [host]");
    System.exit(1);
    int number = Integer.parseInt(args[0]);
    String host = (args.length == 2) ? args[1] : "localhost" ;
    Thread[] threads = new Thread [number];
    InetSocketAddress address = new InetSocketAddress(host, 80);
    for (int i = 0; i < number; i++)
    MultiClient client = new MultiClient(address, Integer.toString(i));
    threads[i] = new Thread(client);
    threads.setDaemon(true);
    for (int i = 0; i < number; i++)
    threads[i].start();
    for (int i = 0; i < number; i++)
    threads[i].join();
    public MultiClient(InetSocketAddress address, String id)
    throws InterruptedException, IOException
    m_id = id;
    Charset charset = Charset.forName("UTF-8");
    m_decoder = charset.newDecoder();
    m_encoder = charset.newEncoder();
    m_channel = SocketChannel.open();
    m_channel.connect(address);
    if (id.equals("0"))
    Socket socket = m_channel.socket();
    System.out.println("SO_SNDBUF=" + socket.getSendBufferSize()
    + ",SO_TIMEOUT=" + socket.getSoTimeout()
    + ",SO_KEEPALIVE=" + socket.getKeepAlive());
    byte[] buf = new byte [1024]; // bufsize = 1K
    Arrays.fill(buf, (byte) m_id.charAt(0));
    m_buffer = ByteBuffer.allocateDirect(1024);
    m_buffer.put(buf);
    m_buffer.flip();
    Thread.currentThread().sleep(50L);
    public void run()
    System.out.print(m_id);
    try
    while (true)
    m_channel.write(m_buffer);
    m_buffer.rewind();
    Thread.currentThread().sleep(1000L);
    catch (IOException ioe)
    ioe.printStackTrace();
    catch (InterruptedException ie)
    System.err.println(ie.toString());
    private String m_id;
    private CharsetEncoder m_encoder;
    private CharsetDecoder m_decoder;
    private SocketChannel m_channel;
    private ByteBuffer m_buffer;

    {This is a crosspost. I posted this earlier today at http://forum.java.sun.com/thread.jsp?forum=4&thread=319822 before I stumbled on a search phrase that located this older thread.
    All follow-ups should be on haam's thread instead of mine. The important point below is that NIO select() behavior (vs. threading IO)  is [b]worse under Windows but better under Solaris. This seems fundamentally broken. }
    My company sells a scalable multi-user server platform built on Java 2.
    It runs under Java 1.3.1 (and 1.4.0 windows) using multiple threads for communications, and 1.4.x (unix) using NIO. We were happy to see that 1.4.1 (windows) fixed the problem drastically limiting the number of selectable ports. :-)
    The bad news is that whatever the VM is doing "under the sheets" to fix the problem seems to perform very poorly in terms of CPU:
    I compared connecting 500 simulated users to a Solaris 8 and a Win2K box. These users were in 25 chat rooms, each sending a chat message every 30 seconds. (There was plenty of memory on each machine. There was no swapping in either case. Clock/CPU type doesn't matter as this isn't about comparing a machine to a machine, but different load characteristics -within- a machine environment.)
                    Threaded IO      NIO/Select
    Solaris 1.4.1     20-30%           15- 20%
    Windows 1.4.1     40-50%           95-100%Numbers are % of CPU as reported by 'top' and the Win2K task manager.
    Both platforms showed the expected significant improvement in memory usage when moving from standard threaded IO to NIO.
    Strangely, the Windows implementation of the VM showed a significant (and unexpected) degradation of NIO performance vs. the threaded model, whereas the Solaris VM behaved as expected: NIO outperformed threaded IO.
    Our best guess is that the Selector fix in 1.4.1 is implemented in some cpu-intensive way; perhaps polling. As a result, we still can't use NIO for Wintel boxes running our server. :-( To us, Selector
    is still broken.
    Has anyone else seen results like this? Have we missed some configuration parameter that will fix this?
    I thought the big upside of using select() was supposed to be performance. :-P
    F. Randall Farmer
    State Software, Inc.
    http://www.statesoftware.com

  • NIO: Strange problem when using ByteBuffer with non-blocking SocketChannel

    Hi,
    I have a server that uses multiplexed, non-blocking I/O with java.nio. When a client connects, the server waits for the message: <system cmd="knock"/>, returns a message and disconnects the client. The clients are shortly serviced in less than a second.
    But the server newer receive anything from about 20% of the clients - even though it is sent. Or with other words: it is received and the data is contained in the ByteBuffer - SocketChannel.read(ByteBuffer) - but a call to ByteBuffer.remaing() returns 0 !!
    ByteBuffer receiveBuf = ByteBuffer.allocate(65536);
    receiveBuf.clear(); // the code is elsewhere used for longer living clients
    int readBytes = channel.read(receiveBuf);
    receiveBuf.flip();
    StringBuffer sb = new StringBuffer();
    System.out.println(" * Remaining: "+receiveBuf.remaining()); // writes: ' * Remaining: 0'
    System.out.println(" * Received: "+new String(receiveBuf.array())); // writes: ' * Received: <system cmd="knock"/>'
    while(receiveBuf.remaining() >= 2) {
      byte b = receiveBuf.get();
      sb.append((char)b);
    System.out.println(" * sb content: "+sb.toString()); // writes: ' * sb content: 'The ByteBuffer clearly receives the correct data, but the ByteBuffer.remaining() returns 0 and therefore the StringBuffer will never have any content.
    The problem seems to occur randomly and for about 20% of the clients (simulated from the same computer and therefore has the same bandwidth and so on).
    Anyone knows what is going on, and how to solve the problem !?

    It's always possible in any read that the number of bytes read is less than the number of bytes requested. You need to keep reading until you have got everything you expected, and cope with every possible error condition on each iteration.
    EJP

  • Non-Blocking Writing and Strings

    Hello.
    My question is simple, is it possible to write strings using a non-blocking method?
    I was praying that there was a method in the NIO API that allowed me to, yet i can't find one.
    If the answer is blatantly obvious please forgive me, i'm tired and hungry :)
    Thank you for looking at this topic

    Strings are written to files or sockets using a certain encoding. I usually use UTF-8, but your application might be different.
    1. Get the SocketChannel from your non-blocking socket.
    SocketChannel ch = mySocket.getChannel(); // mySocket is java.net.Socket2. Make a CharBuffer out of the String you want to send.
    CharBuffer chars = CharBuffer.wrap(myString); // myString is your data3. Encode it so it becomes a ByteBuffer. I'll use the [UTF-8|http://www.joelonsoftware.com/articles/Unicode.html] Charset here.
    ByteBuffer bytes = Charset.forName("UTF-8").encode(chars);4. Use the write(ByteBuffer) method in the SocketChannel from 1.
    ch.write(bytes);Import declarations:
    import java.nio.channels.SocketChannel;
    import java.nio.CharBuffer;
    import java.nio.ByteBuffer;
    import java.nio.charset.Charset;s

  • Non-blocking SocketChannels

    I'm trying to learn how to use non-blocking socket channles, but I haven't found much info (nor luck) so far.
    To learn, I'm building a server and a client. The server accepts input from the clients and process it in only one thread. The clients should send Objects to the server, and the server process them and return the result also as an Object. For this, I'm trying to use ObjectOutputStream and ObjectInputStream.
    The problem I don't know how to solve is that the SocketChannel is in non-bolcking mode, so I can't use their input/output streams (I get a IllegalBlockingModeException). In the server process loop I can reconfigure the SocketChannel to blocking mode to be able to read the Object, but I can't configure it to non-blocking mode again because I get a CancelledKeyException.
    Does anyone know how to work with InputStreams and non-blocking channels? Or where to find more info about it?
    Here are the relevant part of the server code:
    Set ready = selector.selectedKeys();
    Iterator i = ready.iterator();
    while (i.hasNext()) {
       try {
          SelectionKey sk = i.next();
          i.remove();
          if (sk.isAcceptable()) {
             ServerSocketChannel ssc = (ServerSocketChannel)sk.channel();
             SocketChannel sc = ssc.accept();
             sc.configureBlocking(false);
             sc.register(selector, SelectionKey.OP_READ);
          } else if (sk.isReadable()) {
             SocketChannel sc = (SocketChannel)sk.channel();
             // PROBLEM: If the channel is in non-blocking mode
             // I cannot use InputStreams
             sk.cancel();
             sc.configureBlocking(true);
             // Read the object sent by the client
             ObjectInputStream in = new ObjectInputStream(Channels.newInputStream(sc));
             Object o = in.readObject();
             // PROBLEM: Can't put the channel back to non-blocking mode
             sc.configureBlocking(false);
             sc.register(selector, SelectionKey.OP_READ); // CancelledKeyException
       } catch (...){
    }

    In my client, this is working fine:
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    for (int i = 0; i < 30000; i++) {
       oos = new ObjectOutputStream(sc.socket().getOutputStream());
       oos.writeObject(object);
       oos.flush();
       ois = new ObjectInputStream(sc.socket().getInputStream());
       Object o = ois.readObject();
    }But trying to do it like this throws a StreamCorruptedException at the server side.
    ObjectOutputStream oos = new ObjectOutputStream(sc.socket().getOutputStream());
    ObjectInputStream ois = new ObjectInputStream(sc.socket().getInputStream());
    for (int i = 0; i < 30000; i++) {
       oos.writeObject(object);
       oos.flush();
       Object o = ois.readObject();
    }Do you know why?

  • Non-Blocking SocketChannel read give Connection timed out

    Hi,
    My program is using Non-Block NIO SocketChannel for both Server and Client sides. However, if the connection between server and client has been idle for a while, when the client try to communicate with server, it gets blocked for a while (15 minutes) and then receives the following exception:
    java.io.IOException: Connection timed out
         at sun.nio.ch.FileDispatcher.read0(Native Method)
         at sun.nio.ch.SocketDispatcher.read(Unknown Source)
         at sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
         at sun.nio.ch.IOUtil.read(Unknown Source)
         at sun.nio.ch.SocketChannelImpl.read(Unknown Source)
    How can this be since the read is in Non-Blocking mode? Also, is there anyway to determine the timeout without being blocked?

    This would mean that you are trying to read from the socket without having properly completed the connection, which timed out. I would say you are connecting in non-blocking mode but not calling finishConnect() when you get OP_CONNECT.

  • What is the difference between non-blocking and 1:1 oversubscribed?

    Could someone tell me what the difference is between a non-blocked port and one with 1:1 oversubscription?

    "non-blocking port" and "1:1 oversubscription" are the same.    It's also the same when you are saying "line rate".  

  • Non-blocking and terminating processes

    Can someone give me an example of using the host.nonblocking to terminate a process or a window that is opened using a webutil_file_Transfer.DB_To_Client when finished using the opened document.
    I am using oracle 10g developer:
    Thanks

    "non-blocking port" and "1:1 oversubscription" are the same.    It's also the same when you are saying "line rate".  

  • 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?

  • JDK 1.4 nio non-blocking connects don't finish

    I am working with the Linux version of JDK1.4, doing some testing of the
    non-blocking capability. The few tests that I have done have shown some
    strange results:
    - When opening a non-blocking connection to a server which has an
    announcement banner, say such as POP which gives something like:
    +OK pop3 server ready
    then connection seems to be OK and proceed through to completion.
    - When opening a non-blocking connection to a server which is silent, and
    expects me to start the conversation, such as contacting an HTTP server,
    then the Selector.select() never returns to allow me to finish the
    connection.
    Below is a test program which illustrates the problem for me.
    It attempts to open a non-blocking connection to www.yahoo.com on port 80.
    It then drops into a Selector.select() where I am waiting for the chance to
    catch the SelectionKey.OP_CONNECT event and finish connecting, and then send
    a simple HTTP GET request down the wire. That OP_CONNECT event
    never seems to arrive though, and I remain stuck in the select().
    'netstat -na' shows that I am in a connection established state.
    Any insight appreciated,
    -Steve M [email protected]
    ------------------>8 cut here 8<-----------------------
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import java.nio.*;
    import java.nio.channels.*;
    public class NoWorkee
    public static String GET_REQUEST = "GET / HTTP/1.0\r\n\r\n";
        static class Context
            String host;
            int    port;
            ByteBuffer request;
            public Context (String h, int p, ByteBuffer r)
            {host=h; port=p; request=r;}
    Selector sel = null;
    boolean keepGoing = true;
    public NoWorkee()
        throws IOException
        sel = Selector.open();
    public void add(String host, int port)
        throws IOException
        int ops = SelectionKey.OP_CONNECT;
        // create non-blocking socket, and initiate connect operation
        SocketChannel sc = SocketChannel.open();
        sc.configureBlocking(false);
        sc.connect(new InetSocketAddress(InetAddress.getByName(host), port));
        SelectionKey sk;
        try
            sk = sc.register(sel, ops);
            System.out.println ( "sc.register looks good connected=" +
                sc.isConnected() + ", isConnectionPending=" +
                sc.isConnectionPending());
            sk.attach(new Context(host, port, ByteBuffer.wrap(GET_REQUEST.getBytes())));
        catch (IOException x)
            x.printStackTrace();
            sc.close();
    public void run()
        throws IOException
        keepGoing = true;
        System.out.println ( "Selecting " + sel.keys().size() + " SelectKeys");
        while (keepGoing)
            final long before = System.currentTimeMillis();
            final int numReady = sel.select();
            //final int numReady = sel.select(1000);
            final long after = System.currentTimeMillis();
            System.out.println ( "Blocked " + (after-before) + " ms, numReady=" + numReady);
            if (numReady > 0)
                Set readyKeys = sel.selectedKeys();
                System.out.println ( "Selected keys size " + readyKeys.size());
                for (Iterator it = readyKeys.iterator(); it.hasNext();)
                    SelectionKey sk = (SelectionKey)it.next();
                    SocketChannel sockChan = (SocketChannel)sk.channel();
                    Context ctx = (Context)sk.attachment();
                    System.out.println ( "Servicing host " + ctx.host + " port "
                                 ctx.port);
    System.out.println ( "1");
                    if (sk.isConnectable())
                        if (sockChan.finishConnect())
                            System.out.println ( "Finished connecting success "
    + sockChan);
                            int ops = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
                            sk.interestOps (ops);
                        else
                            System.out.println ( "Could not finishConnect for "
                                sockChan);
                            sk.cancel();
                            sockChan.close();
    System.out.println ( "2");
                    if (sk.isAcceptable())
                        System.out.println ( "in sk.isAcceptable() block");
    System.out.println ( "3");
                    if (sk.isReadable())
                        System.out.println ( "in sk.isReadable() block");
                        byte rawBuff[] = new byte[32 * 1024];
                        ByteBuffer buff = ByteBuffer.wrap(rawBuff);
                        int numRead = -1;
                        while (0 < (numRead = sockChan.read(buff)))
                            System.out.println ( "numRead = " + numRead);
                            for (int i = 0; i < numRead; i++)
                                System.out.print((char)rawBuff);
    System.out.println ( "numRead = " + numRead);
    System.out.println ( "4");
    if (sk.isWritable())
    System.out.println ( "in sk.isReadable() block");
    int numWritten = -1;
    if (null != ctx.request)
    numWritten = sockChan.write(ctx.request);
    if (!ctx.request.hasRemaining())
    sk.interestOps(sk.interestOps() &
    ~SelectionKey.OP_WRITE);
    System.out.println ( "numWritten = " + numWritten);
    //else
    // service timeouts
    public static void main (String arg[])
    try
    NoWorkee bla = new NoWorkee();
    bla.add ("www.yahoo.com", 80);
    bla.run();
    catch (Exception e)
    e.printStackTrace();
    ------------------>8 cut here 8<-----------------------

    Just for the benefit of anyone who might be seeing the same problem, it looks like bug 4457776 accurately describes the problem that I was having above.
    I am downloading j2sdk-1_4_0-beta2-linux-i386-rpm.bin to see if that fixed it.
    Reference:
    http://developer.java.sun.com/developer/bugParade/bugs/4457776.html

  • 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

  • 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

  • What is non blocking IO?

    I have heard that 1.4 supports non blocking IO, and that this is greath for servers. What is it, how does it work and why is it so good?

    I could be wrong - but if they have not yet done so
    a good optimization would be to rearrange the
    select list - such that the sockets that have
    an event appears at the top of the list.
    This way - when the select completes - it tells
    you that there are - say 2 - active events - you
    would then just read the first two channels on
    the select list.From the API javadoc:
    The selected-key set is the set of keys such that each key's channel was detected to be ready for at least one of the operations identified in the key's interest set during a prior selection operation. This set is returned by the selectedKeys method. The selected-key set is always a subset of the key set.
    ie- select and iterate. No polling involved.
    They just completed the java EventListener model
    for the GUI. It would have been simple and clean
    to implement a similar model for io. You have
    the io channel - you would just attach an event
    listener to it much like you would do for a control.
    When an io finishes on a channel, you would be
    told immediately the channel that the io completed
    and what event occured - read, write etc.
    Now you could have a million sockets
    ( if ever unix could support that many file
    discriptors )
    and you when an io completes no need to poll
    a bunch of idle sockets.Question: What thread would this run in?
    * Does it run in the network layer? How many concurrent event notifications can the network layer at any one time? Is it likely it would be an EventQueue-esque single thread?
    * Does it spawn a new thread for each event? This would certainly yield worse results than spawning a new thread for each socket, since each socket would generate a vast number of events.
    * Does it have a thread pool to deal with the events? Then you would be using exactly the same model as java.nio's Selector.
    FYI: The windows NT asynchronous IO model uses
    an event model - IO completion ports. It is far more
    modern, advanced and efficient that the select / poll
    model used in unix.Do you have any links for more information?
    Sun could have incorporated the most modern / best
    features into java and make it competitive. Instead
    they went for least common denominator.Sun's nio package was (somewhat) based on a community project, and was integrated into Java on JSR-051
    http://www.cs.berkeley.edu/~mdw/proj/java-nbio/
    If there were such an initiative for NT-style asynchronous IO, and this was proven to be more efficient, then I imagine it will be much more likely to be integrated with the language.
    If it isn't, you could still use the community-based implementation, as you could with the nbio package before 1.4 was released.
    Just because Sun doesn't do something, doesn't mean you can't!

  • Non-blocking connection on a SocketChannel?

    I'm trying out the non-blocking connection of a SocketChannel. So I wrote the following test code and supply a list of IPs (both good and bad IPs). But disregard the IPs I always get the result of a channel being in connection pending state (even for some bogus IPs). Any help will be great.
    public class ConnectTest
        public static void main(String[] args) throws
    Exception
            List<SocketChannel> channels = new ArrayList<SocketChannel>();
            for ( String s: args )
                SocketChannel channel = SocketChannel.open();
                channel.configureBlocking(false);
                channels.add(channel);        
                InetSocketAddress remote = new InetSocketAddress(s, 80);
                channel.connect(remote);
            System.out.println("wait for timeout...");
            Thread.sleep(10000);
            for ( SocketChannel c : channels )
                if ( c.isConnected() )
                    System.out.println(c.socket().getInetAddress() + " connected ");
                else if ( c.isConnectionPending() )
                    System.out.println(c.socket().getInetAddress() + " connection pending ");               
                else
                    System.out.println(c.socket().getInetAddress() + " timeout ");
                c.close();
    }

    Forget the sleep: use a Selector, selecting on OP_CONNECT. When you get it, call SocketChannel.finishConnect() for the channel(s) selected. If that method returns 'true', the connection is complete. If it returns 'false', the connection is still pending (and in fact OP_CONNECT should not have fired); if it throws an exception, the connection attempt has failed.
    If the connection is complete you must also deregister it for OP_CONNECT before registering it for OP_READ or OP_WRITE.

Maybe you are looking for

  • Is there a way to automatically add text to video; the text gleaned from order data?

    is there a way to automatically add text to video; the text gleaned from order data?

  • About vertical format (iBooks Author)

    Hello people! This is my first entry, but not the first time I check for your support. This is because I can't figure something out, so you might help me a little. This is my problem: some creative son of his/her mother decided to propose vertical co

  • [SOLVED] Sound problems after upgrading

    Forgive me in advance for any vagueness on my part. I confess that I'm not entirely clear on how the sound on my system is set up - I've generally just been taking the path of least resistance, and as long as it works I don't worry about it too much.

  • Owb 9.2 compatible w/ HP-UX 9.2.3?

    Is OWB 9.2 compatible with HP-UX 9.2.3? A Follow-up Question. Where can I find certification documemntation for older releases of Oracle products?

  • \Boot\BSD issues

    Hello, I was recently mapping network drives to my windows 7 machine through windows exporer. I mapped two drives, I cannot remember exactly but I beleive they had the letters Y: and X:.  on researting the computer, I got a bootloader error, with a b