Blocking read on a FIFO

My java program needs to read data from a FIFO file and then block when the data ends and wait for more data.
I can achieve the desired effect with something like
while(true) {
    while(myReader.ready()) {
        ... read data here ....
}... but this eats the cpu. Is there a way to truly do a blocking read on the file while waiting for more data?
Thanks!

I apologize if it was ambiguous. It is a FIFO file on a Linux system which you can create with the mkfifo or mknod commands. As far as I'm aware it can be read from and written to like a regular file.
Using while(myReader.read()) gives the desired behavior, but consumes the CPU like a while(true) loop.
I can ameliorate the problem by just waking up a thread periodically to check the file, but I was hoping for a non-polling solution.

Similar Messages

  • Implementing non-blocking read

    Hi all
    I have some doubts about implementing non-blocking io in my application.
    I am using Jsch library (an ssh implementation) to open an ssh connection with a host. The API only provides me with methods to open a connection and retreive the input & output streams. I want to make my read on inputstream non-blocking.In such a case is it possible to use nio for the purpose?
    If it's not possible then I am planning to use threading to make read() non-blocking. Here also i need some clarifications. I am planning to use a ThreadPoolExecutor to create a thread pool for reading data. SO whenever i have a read i'll assign this task to the pool which will use one of the free threads to execute the inputStresm.read().
    Now the question is if one of the threads in this pool blocks forever during a read since it didn't get any response from the other side, is there a way to stop that read and make that thread free again to execute more tasks? or will the thread block forever till the application is closed?
    In my case i cannot afford to have too many such blocked threads, since this application will not be restarted very often. Once it is started it can go on for may be days or months.
    Please suggest what would be best in my case taking into account performance as most important factor.
    Thanks in advance.
    Anu

    endasil wrote:
    First of all, let me state that I agree with the others in saying that I don't fully agree with your premises.
    That said, I believe that this does a non-blocking read based on the contract of InputStream.available() and .read(byte[], int, int):
    private int nonBlockingRead(InputStream in, byte[] buffer) throws IOException {
    return in.read(buffer, 0, Math.min(in.available(), buffer.length));
    If the InputStream is obtained from a JSSE socket then it is my understanding that available() always returns zero. This is allowed under the InputStream.available() contract as defined in the Javadoc - http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#available() . If I am right then your code will never read anything from a JSSE socket InputStream and I would suspect that Jsch is using JSSE sockets.

  • I am writing datas into a FIFO ,i am reading datas from fifo .but when i am writing datas like a a(0),a(1),a(2 like that.when i am reading dating datas a(0)comes to a(3 ) rd place .what is the reason ?

    I am writing datas into a FIFO in FPGA Target side  ,i am reading datas from fifo in windows host side  .but when i am writing datas like a a(0),a(1),a(2 like that.when i am reading dating datas a(0)comes to a(3 ) rd place, a(1) comes to a a(0) .what is the reason ?

    Please use a shorter title in your subject line and not post the entire question in therre.  (See the subject line I created.)   There is also no such word as "datas".  Data is already plural.
    Please read http://stackoverflow.com/help/how-to-ask.  Your question is hard to read because you aren't using proper punctuation and capitalization of your sentences.  It looks like one run-on sentence.
    Beyond that, it is impossible to help you solve our problem with just your question.  Please provide some more information.  Perhaps even attach code we can look at.  Show us what the data you are sending is supposed to look like, and what it actually looks like.

  • Unable to relate consistent reads with number of phsyical block reads

    HI ,
    The question is we have observed the consistent reads are much more than total buffers required to give the results back.
    I have flushed the buffer_cache before executing the query and also queried the V$BH to know the buffer details for these objects ...after the flush before firing the query we don't have any buffers regarding these tables. Which is expected.
    We are doing DB file sequential reads through the plan and it will result into a single block read at a time.
    Please take a close look at "TABLE ACCESS BY INDEX ROWID CMPGN_DIM (cr=45379 pr=22949 pw=0 time=52434931 us)" line in the below row source plan..
    Here we have only 22949 physical reads means 22949 data buffers but we are seeing 45379 consistent gets.
    Note: We have the CMPGN_DIM and AD_GRP tables are in 4M block size table space and we have only than the default db_cache_size . My database block size is 8192.
    Can you please help me in understand how the 22949 sequential reads result into 45379 consistant gets.
    Even the V$BH query buffer details matches with physical reads .
    query row source plan from 10043 trace:
    27 SORT ORDER BY (cr=92355 pr=47396 pw=0 time=359030364 us)
    27 WINDOW SORT (cr=92355 pr=47396 pw=0 time=359030088 us)
    27 NESTED LOOPS OUTER (cr=92355 pr=47396 pw=0 time=359094569 us)
    27 NESTED LOOPS OUTER (cr=92276 pr=47395 pw=0 time=359041825 us)
    27 VIEW (cr=92197 pr=47393 pw=0 time=358984314 us)
    27 UNION-ALL (cr=92197 pr=47393 pw=0 time=358984120 us)
    26 HASH GROUP BY (cr=92197 pr=47393 pw=0 time=358983665 us)
    9400 VIEW (cr=92197 pr=47393 pw=0 time=359094286 us)
    9400 COUNT (cr=92197 pr=47393 pw=0 time=359056676 us)
    9400 VIEW (cr=92197 pr=47393 pw=0 time=359009672 us)
    9400 SORT ORDER BY (cr=92197 pr=47393 pw=0 time=358972063 us)
    9400 HASH JOIN OUTER (cr=92197 pr=47393 pw=0 time=358954170 us)
    9400 VIEW (cr=92191 pr=47387 pw=0 time=349796124 us)
    9400 HASH JOIN (cr=92191 pr=47387 pw=0 time=349758517 us)
    94 TABLE ACCESS BY INDEX ROWID CMPGN_DIM (cr=45379 pr=22949 pw=0 time=52434931 us)
    50700 INDEX RANGE SCAN IDX_CMPGN_DIM_UK1 (cr=351 pr=349 pw=0 time=1915239 us)(object id 55617)
    60335 TABLE ACCESS BY INDEX ROWID AD_GRP (cr=46812 pr=24438 pw=0 time=208234661 us)
    60335 INDEX RANGE SCAN IDX_AD_GRP2 (cr=613 pr=611 pw=0 time=13350221 us)(object id 10072801)
    7 VIEW (cr=6 pr=6 pw=0 time=72933 us)
    7 HASH GROUP BY (cr=6 pr=6 pw=0 time=72898 us)
    162 PARTITION RANGE SINGLE PARTITION: 4 4 (cr=6 pr=6 pw=0 time=45363 us)
    162 PARTITION HASH SINGLE PARTITION: 676 676 (cr=6 pr=6 pw=0 time=44690 us)
    162 INDEX RANGE SCAN PK_AD_GRP_DTL_FACT PARTITION: 3748 3748 (cr=6 pr=6 pw=0 time=44031 us)(object id 8347241)
    1 FAST DUAL (cr=0 pr=0 pw=0 time=9 us)
    25 TABLE ACCESS BY INDEX ROWID AD_GRP (cr=79 pr=2 pw=0 time=29817 us)

    I think that I understand your question. The consistent gets statistic (CR) indicates the number of times blocks were accessed in memory, and doing so possibly required undo to be applied to the blocks to provide a consistent get. The physical read statistic (PR) indicates the number of blocks that were accessed from disk. The consistent gets statistic may be very close to the physical reads statistic, or very different depending on several factors. A test case might best explain why the CR and PR statistics may differ significantly. First, creating the test objects:
    CREATE TABLE T1 AS
    SELECT
      ROWNUM C1,
      1000000-ROWNUM C2,
      RPAD(TO_CHAR(ROWNUM),800,'X') C3
    FROM
      DUAL
    CONNECT BY
      LEVEL<=1000000;
    CREATE INDEX INT_T1_C1 ON T1(C1);
    CREATE INDEX INT_T1_C2 ON T1(C2);
    CREATE TABLE T2 AS
    SELECT
      ROWNUM C1,
      1000000-ROWNUM C2,
      RPAD(TO_CHAR(ROWNUM),800,'X') C3
    FROM
      DUAL
    CONNECT BY
      LEVEL<=100000;
    COMMIT;
    EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>USER,TABNAME=>'T1',CASCADE=>TRUE,ESTIMATE_PERCENT=>NULL)
    EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>USER,TABNAME=>'T2',CASCADE=>TRUE,ESTIMATE_PERCENT=>NULL)We now have 2 tables, the first with 1,000,000 rows with about 8 rows per block and having 2 indexes, and the second table with 100,000 rows and no indexes.
    SELECT
      TABLE_NAME,
      PCT_FREE,
      NUM_ROWS,
      BLOCKS
    FROM
      USER_TABLES
    WHERE
      TABLE_NAME IN ('T1','T2');
    TABLE_NAME   PCT_FREE   NUM_ROWS     BLOCKS
    T1                 10    1000000     125597
    T2                 10     100000      12655
    COLUMN INDEX_NAME FORMAT A10
    SELECT
      INDEX_NAME,
      BLEVEL,
      LEAF_BLOCKS,
      DISTINCT_KEYS DK,
      CLUSTERING_FACTOR CF,
      NUM_ROWS
    FROM
      USER_INDEXES
    WHERE
      TABLE_NAME IN ('T1','T2');
    INDEX_NAME     BLEVEL LEAF_BLOCKS         DK         CF   NUM_ROWS
    INT_T1_C1           2        2226    1000000     125000    1000000
    INT_T1_C2           2        2226    1000000     125000    1000000Now a test script to try a couple experiments with the two tables:
    SET LIN 120
    SET AUTOTRACE TRACEONLY STATISTICS EXPLAIN
    SET TIMING ON
    SPOOL C:\MYTEST.TXT
    ALTER SESSION SET STATISTICS_LEVEL=TYPICAL;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SESSION SET TRACEFILE_IDENTIFIER = 'TEST1';
    ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 8';
    SELECT /*+ USE_HASH(T1 T2) */
      T1.C1,
      T2.C2,
      T1.C3
    FROM
      T1,
      T2
    WHERE
      T1.C2=T2.C2
      AND T1.C2 BETWEEN 900000 AND 1000000;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SESSION SET TRACEFILE_IDENTIFIER = 'TEST2';
    SELECT /*+ USE_NL(T1 T2) */
      T1.C1,
      T2.C2,
      T1.C3
    FROM
      T1,
      T2
    WHERE
      T1.C2=T2.C2
      AND T1.C2 BETWEEN 900000 AND 1000000;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SESSION SET TRACEFILE_IDENTIFIER = 'TEST3';
    SELECT /*+ USE_HASH(T1 T2) */
      T1.C1,
      T2.C2,
      T1.C3
    FROM
      T1,
      T2
    WHERE
      T1.C1=T2.C1
      AND T1.C1 BETWEEN 1 AND 100000;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SYSTEM FLUSH BUFFER_CACHE;
    ALTER SESSION SET TRACEFILE_IDENTIFIER = 'TEST4';
    SELECT /*+ USE_NL(T1 T2) */
      T1.C1,
      T2.C2,
      T1.C3
    FROM
      T1,
      T2
    WHERE
      T1.C1=T2.C1
      AND T1.C1 BETWEEN 1 AND 100000;
    ALTER SESSION SET TRACEFILE_IDENTIFIER = 'TEST5';
    SELECT /*+ USE_NL(T1 T2) FIND_ME */
      T1.C1,
      T2.C2,
      T1.C3
    FROM
      T1,
      T2
    WHERE
      T1.C1=T2.C1
      AND T1.C1 BETWEEN 1 AND 100000;
    SET AUTOTRACE OFF
    ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT OFF';
    SPOOL OFFTest script output follows (note that the script was executed twice so that statistics related to the hard parse would be excluded):
    SQL> SELECT /*+ USE_HASH(T1 T2) */
      2    T1.C1,
      3    T2.C2,
      4    T1.C3
      5  FROM
      6    T1,
      7    T2
      8  WHERE
      9    T1.C2=T2.C2
    10    AND T1.C2 BETWEEN 900000 AND 1000000;
    100000 rows selected.
    Elapsed: 00:00:22.65
    Execution Plan
    Plan hash value: 488978626                                                                                             
    | Id  | Operation                    | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |                     
    |   0 | SELECT STATEMENT             |           | 99999 |    77M|       | 20139   (1)| 00:04:02 |                     
    |*  1 |  HASH JOIN                   |           | 99999 |    77M|  1664K| 20139   (1)| 00:04:02 |                     
    |*  2 |   TABLE ACCESS FULL          | T2        |   100K|   488K|       |  3435   (1)| 00:00:42 |                     
    |   3 |   TABLE ACCESS BY INDEX ROWID| T1        |   100K|    77M|       | 12733   (1)| 00:02:33 |                     
    |*  4 |    INDEX RANGE SCAN          | INT_T1_C2 |   100K|       |       |   226   (1)| 00:00:03 |                     
    Predicate Information (identified by operation id):                                                                    
       1 - access("T1"."C2"="T2"."C2")                                                                                     
       2 - filter("T2"."C2">=900000 AND "T2"."C2"<=1000000)                                                                
       4 - access("T1"."C2">=900000 AND "T1"."C2"<=1000000)                                                                
    Statistics
              0  recursive calls                                                                                           
              0  db block gets                                                                                             
          37721  consistent gets                                                                                           
          25226  physical reads                                                                                            
              0  redo size                                                                                                 
       82555058  bytes sent via SQL*Net to client                                                                          
          73722  bytes received via SQL*Net from client                                                                    
           6668  SQL*Net roundtrips to/from client                                                                         
              0  sorts (memory)                                                                                            
              0  sorts (disk)                                                                                              
         100000  rows processed                                                                                            
    STAT lines from the 10046 trace:
    STAT #37 id=1 cnt=100000 pid=0 pos=1 obj=0 op='HASH JOIN  (cr=37721 pr=25226 pw=0 time=106305676 us)'
    STAT #37 id=2 cnt=100000 pid=1 pos=1 obj=48144 op='TABLE ACCESS FULL T2 (cr=12511 pr=12501 pw=0 time=13403966 us)'
    STAT #37 id=3 cnt=100000 pid=1 pos=2 obj=48141 op='TABLE ACCESS BY INDEX ROWID T1 (cr=25210 pr=12725 pw=0 time=103903740 us)'
    STAT #37 id=4 cnt=100000 pid=3 pos=1 obj=48143 op='INDEX RANGE SCAN INT_T1_C2 (cr=6877 pr=225 pw=0 time=503602 us)'Elapsed: 00:00:00.01
    SQL> SELECT /*+ USE_NL(T1 T2) */
      2    T1.C1,
      3    T2.C2,
      4    T1.C3
      5  FROM
      6    T1,
      7    T2
      8  WHERE
      9    T1.C2=T2.C2
    10    AND T1.C2 BETWEEN 900000 AND 1000000;
    100000 rows selected.
    Elapsed: 00:00:20.17
    Execution Plan
    Plan hash value: 1773329022                                                                                            
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |                              
    |   0 | SELECT STATEMENT            |           | 99999 |    77M|   303K  (1)| 01:00:43 |                              
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |     1 |   810 |     3   (0)| 00:00:01 |                              
    |   2 |   NESTED LOOPS              |           | 99999 |    77M|   303K  (1)| 01:00:43 |                              
    |*  3 |    TABLE ACCESS FULL        | T2        |   100K|   488K|  3435   (1)| 00:00:42 |                              
    |*  4 |    INDEX RANGE SCAN         | INT_T1_C2 |     1 |       |     2   (0)| 00:00:01 |                              
    Predicate Information (identified by operation id):                                                                    
       3 - filter("T2"."C2">=900000 AND "T2"."C2"<=1000000)                                                                
       4 - access("T1"."C2"="T2"."C2")                                                                                     
           filter("T1"."C2">=900000 AND "T1"."C2"<=1000000)                                                                
    Statistics
              0  recursive calls                                                                                           
              0  db block gets                                                                                             
         250219  consistent gets                                                                                           
          25227  physical reads                                                                                            
              0  redo size                                                                                                 
       82555058  bytes sent via SQL*Net to client                                                                          
          73722  bytes received via SQL*Net from client                                                                    
           6668  SQL*Net roundtrips to/from client                                                                         
              0  sorts (memory)                                                                                            
              0  sorts (disk)                                                                                              
         100000  rows processed                                                                                            
    STAT lines from the 10046 trace:
    STAT #36 id=1 cnt=100000 pid=0 pos=1 obj=48141 op='TABLE ACCESS BY INDEX ROWID T1 (cr=250219 pr=25227 pw=0 time=61410637 us)'
    STAT #36 id=2 cnt=200001 pid=1 pos=1 obj=0 op='NESTED LOOPS  (cr=231886 pr=12727 pw=0 time=3000840 us)'
    STAT #36 id=3 cnt=100000 pid=2 pos=1 obj=48144 op='TABLE ACCESS FULL T2 (cr=18344 pr=12501 pw=0 time=14103896 us)'
    STAT #36 id=4 cnt=100000 pid=2 pos=2 obj=48143 op='INDEX RANGE SCAN INT_T1_C2 (cr=213542 pr=226 pw=0 time=1929742 us)'
    SQL> SELECT /*+ USE_HASH(T1 T2) */
      2    T1.C1,
      3    T2.C2,
      4    T1.C3
      5  FROM
      6    T1,
      7    T2
      8  WHERE
      9    T1.C1=T2.C1
    10    AND T1.C1 BETWEEN 1 AND 100000;
    100000 rows selected.
    Elapsed: 00:00:20.35
    Execution Plan
    Plan hash value: 689276421                                                                                             
    | Id  | Operation                    | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |                     
    |   0 | SELECT STATEMENT             |           | 99999 |    77M|       | 20143   (1)| 00:04:02 |                     
    |*  1 |  HASH JOIN                   |           | 99999 |    77M|  2152K| 20143   (1)| 00:04:02 |                     
    |*  2 |   TABLE ACCESS FULL          | T2        |   100K|   976K|       |  3435   (1)| 00:00:42 |                     
    |   3 |   TABLE ACCESS BY INDEX ROWID| T1        |   100K|    76M|       | 12733   (1)| 00:02:33 |                     
    |*  4 |    INDEX RANGE SCAN          | INT_T1_C1 |   100K|       |       |   226   (1)| 00:00:03 |                     
    Predicate Information (identified by operation id):                                                                    
       1 - access("T1"."C1"="T2"."C1")                                                                                     
       2 - filter("T2"."C1">=1 AND "T2"."C1"<=100000)                                                                      
       4 - access("T1"."C1">=1 AND "T1"."C1"<=100000)                                                                      
    Statistics
              0  recursive calls                                                                                           
              0  db block gets                                                                                             
          37720  consistent gets                                                                                           
          25225  physical reads                                                                                            
              0  redo size                                                                                                 
       82555058  bytes sent via SQL*Net to client                                                                          
          73722  bytes received via SQL*Net from client                                                                    
           6668  SQL*Net roundtrips to/from client                                                                         
              0  sorts (memory)                                                                                            
              0  sorts (disk)                                                                                              
         100000  rows processed                                                                                            
    STAT lines from the 10046 trace:
    STAT #38 id=1 cnt=100000 pid=0 pos=1 obj=0 op='HASH JOIN  (cr=37720 pr=25225 pw=0 time=69225424 us)'
    STAT #38 id=2 cnt=100000 pid=1 pos=1 obj=48144 op='TABLE ACCESS FULL T2 (cr=12511 pr=12501 pw=0 time=13204971 us)'
    STAT #38 id=3 cnt=100000 pid=1 pos=2 obj=48141 op='TABLE ACCESS BY INDEX ROWID T1 (cr=25209 pr=12724 pw=0 time=66504913 us)'
    STAT #38 id=4 cnt=100000 pid=3 pos=1 obj=48142 op='INDEX RANGE SCAN INT_T1_C1 (cr=6876 pr=224 pw=0 time=604405 us)'
    SQL> SELECT /*+ USE_NL(T1 T2) */
      2    T1.C1,
      3    T2.C2,
      4    T1.C3
      5  FROM
      6    T1,
      7    T2
      8  WHERE
      9    T1.C1=T2.C1
    10    AND T1.C1 BETWEEN 1 AND 100000;
    100000 rows selected.
    Elapsed: 00:00:28.11
    Execution Plan
    Plan hash value: 1467726760                                                                                            
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |                              
    |   0 | SELECT STATEMENT            |           | 99999 |    77M|   303K  (1)| 01:00:43 |                              
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |     1 |   806 |     3   (0)| 00:00:01 |                              
    |   2 |   NESTED LOOPS              |           | 99999 |    77M|   303K  (1)| 01:00:43 |                              
    |*  3 |    TABLE ACCESS FULL        | T2        |   100K|   976K|  3435   (1)| 00:00:42 |                              
    |*  4 |    INDEX RANGE SCAN         | INT_T1_C1 |     1 |       |     2   (0)| 00:00:01 |                              
    Predicate Information (identified by operation id):                                                                    
       3 - filter("T2"."C1">=1 AND "T2"."C1"<=100000)                                                                      
       4 - access("T1"."C1"="T2"."C1")                                                                                     
           filter("T1"."C1"<=100000 AND "T1"."C1">=1)                                                                      
    Statistics
              0  recursive calls                                                                                           
              0  db block gets                                                                                             
         250218  consistent gets                                                                                           
          25225  physical reads                                                                                            
              0  redo size                                                                                                 
       82555058  bytes sent via SQL*Net to client                                                                          
          73722  bytes received via SQL*Net from client                                                                    
           6668  SQL*Net roundtrips to/from client                                                                         
              0  sorts (memory)                                                                                            
              0  sorts (disk)                                                                                              
         100000  rows processed                                                                                            
    STAT lines from the 10046 trace:
    STAT #26 id=1 cnt=100000 pid=0 pos=1 obj=48141 op='TABLE ACCESS BY INDEX ROWID T1 (cr=250218 pr=25225 pw=0 time=80712592 us)'
    STAT #26 id=2 cnt=200001 pid=1 pos=1 obj=0 op='NESTED LOOPS  (cr=231885 pr=12725 pw=0 time=4601151 us)'
    STAT #26 id=3 cnt=100000 pid=2 pos=1 obj=48144 op='TABLE ACCESS FULL T2 (cr=18344 pr=12501 pw=0 time=17704737 us)'
    STAT #26 id=4 cnt=100000 pid=2 pos=2 obj=48142 op='INDEX RANGE SCAN INT_T1_C1 (cr=213541 pr=224 pw=0 time=2683089 us)'
    SQL> SELECT /*+ USE_NL(T1 T2) FIND_ME */
      2    T1.C1,
      3    T2.C2,
      4    T1.C3
      5  FROM
      6    T1,
      7    T2
      8  WHERE
      9    T1.C1=T2.C1
    10    AND T1.C1 BETWEEN 1 AND 100000;
    100000 rows selected.
    Elapsed: 00:00:17.81
    Execution Plan
    Plan hash value: 1467726760                                                                                            
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |                              
    |   0 | SELECT STATEMENT            |           | 99999 |    77M|   303K  (1)| 01:00:43 |                              
    |   1 |  TABLE ACCESS BY INDEX ROWID| T1        |     1 |   806 |     3   (0)| 00:00:01 |                              
    |   2 |   NESTED LOOPS              |           | 99999 |    77M|   303K  (1)| 01:00:43 |                              
    |*  3 |    TABLE ACCESS FULL        | T2        |   100K|   976K|  3435   (1)| 00:00:42 |                              
    |*  4 |    INDEX RANGE SCAN         | INT_T1_C1 |     1 |       |     2   (0)| 00:00:01 |                              
    Predicate Information (identified by operation id):                                                                    
       3 - filter("T2"."C1">=1 AND "T2"."C1"<=100000)                                                                      
       4 - access("T1"."C1"="T2"."C1")                                                                                     
           filter("T1"."C1"<=100000 AND "T1"."C1">=1)                                                                      
    Statistics
              0  recursive calls                                                                                           
              0  db block gets                                                                                             
         250218  consistent gets                                                                                           
              0  physical reads                                                                                            
              0  redo size                                                                                                 
       82555058  bytes sent via SQL*Net to client                                                                          
          73722  bytes received via SQL*Net from client                                                                    
           6668  SQL*Net roundtrips to/from client                                                                         
              0  sorts (memory)                                                                                            
              0  sorts (disk)                                                                                              
         100000  rows processed                                                                                            
    STAT lines from the 10046 trace:
    STAT #36 id=1 cnt=100000 pid=0 pos=1 obj=48141 op='TABLE ACCESS BY INDEX ROWID T1 (cr=250218 pr=0 pw=0 time=6000438 us)'
    STAT #36 id=2 cnt=200001 pid=1 pos=1 obj=0 op='NESTED LOOPS  (cr=231885 pr=0 pw=0 time=2401295 us)'
    STAT #36 id=3 cnt=100000 pid=2 pos=1 obj=48144 op='TABLE ACCESS FULL T2 (cr=18344 pr=0 pw=0 time=1400071 us)'
    STAT #36 id=4 cnt=100000 pid=2 pos=2 obj=48142 op='INDEX RANGE SCAN INT_T1_C1 (cr=213541 pr=0 pw=0 time=2435627 us)'So, what does the above mean? Why would a forced execution plan change the number of consistent gets? Why would not flushing the buffer cache cause the PR statistic to drop to 0, yet not change the CR statistic?
    Charles Hooper
    IT Manager/Oracle DBA
    K&M Machine-Fabricating, Inc.

  • Single block read for Sort

    I’m creating a temp table with following SQL. Table temp2 is 50GB in size with 120M rows. I noticed during SORT operation , it’s performing lots of single block reads on Temp tablespace. Why it’s doing single block reads on temp??
    Also, Is there any other way to make this quicker?
    I'm on 10gR2 with Auto PGA/SGA. PGA Aggregate is 5GB and SGA is 12GB.
    create table t_temp nologging parallel(degree 4 )
    as
    select /*+ parallel(t1,4) */ * from temp2 partition(P2008)  t1
    order by custkey
        SID Wait State    EVENT                               P1                         P2              P3                    SEQ# % TotTime TEventTime(ms)  DistEvnts Avgtime(ms)/Evnt
       2165 WAITING       direct path read temp               file number= 5001          first dba=      block cnt= 1                     .02           .253          1             .253
                                                                                         88791
       2165 WAITING       direct path read temp               file number= 5001          first dba=      block cnt= 1                     .02           .253          1             .253
                                                                                         412771
       2165 WAITING       direct path read temp               file number= 5001          first dba=      block cnt= 1                     .02           .253          1             .253
                                                                                         421465
       2165 WAITING       direct path read temp               file number= 5001          first dba=      block cnt= 1                     .02           .253          1             .253
                                                                                         691141
       2165 WAITING       direct path read temp               file number= 5001          first dba=      block cnt= 1                     .02           .253          1             .253
                                                                                         1295425
    Here is  Temp table space properties…
    Name                    INITK    NEXTK MINEX MAXEX PCTI CNTS      EXMGMT     ALOCTYPE  SEGMGM STATUS
    TEMP                     1024     1024     1          0 TEMPORARY LOCAL      UNIFORM   MANUAL ONLINEEdited by: user4529833 on Feb 5, 2009 9:05 AM

    user4529833 wrote:
    Thanks Jonathan.
    I will do that and post the results... One questions though, how to correct this unexpected side-effect of asynchronous reads... ( Assuming it's the case )
    If the assumption is correct, then it's not really something that needs to be corrected. Because of the overlapping of I/Os, there may be lots of I/Os that never make it into wait time, so a single process could be going:
    give me 12 blocks
    give me 12 blocks
    give me 12 blocks
    give me 12 blocks
    give me a block
    of which you see only the "give me a block".
    That's why the 10033 is an important diagnostic - it will help you decide whether or not "everything" is a single block read, or whether the single block reads are a very tiny fraction of the total I/O that also happens to become visible for some reason.
    how does oracle perform sort for SQLs I have given..
    1) read & sort the data for custid coulmn with rowids and dump it temp (quite likely)
    2) read the rowids from temp and start loading row to temp table..I'd have to check the execution to give you a definite answer but the basic strategy would be:
    <ul>
    Two sets of PX slaves.
    Set one reads a chunk of the source table picking up all the relevant columns for the result table.
    Because of the ORDER BY clause layer one does a range-based distribution of data to the second set of slaves - along the lines of "slave 1 gets custid less than 1M", "slave 2 gets custid between 1M and 2M" and so on. Because entire rows are passed between the two sets of slaves, you can see a LOT of PQ traffic going on. (People sometimes increase the "PX message size" parameter because of the volume of traffic and the size of the rows).
    Set two slaves accumulate, and sort the incoming data sets. Each sorted row carries ALL the columns, there is no "sort the custkey/rowids only" strategy. The sorting may spill to temp - given your "select *", the amount of temp space used may actually be greater than the size of the source table.
    Each set two slave creates its own "private table" with its results.
    The query coordinator links the "private table" metadata in the data dictionay in the right order to create the final table.
    </ul>
    Regards
    Jonathan Lewis
    http://jonathanlewis.wordpress.com
    http://www.jlcomp.demon.co.uk
    "Science is more than a body of knowledge; it is a way of thinking"
    Carl Sagan
    To post code, statspack/AWR report, execution plans or trace files, start and end the section with the tag {noformat}{noformat} (lowercase, curly brackets, no spaces) so that the text appears in fixed format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Interrupt() on SocketChannel blocking read()

    I'm having a problem gracefully shutting down a thread while it is blocked in a SocketChannel read() function. According to the nio.channel and Thread docs, if a thread is blocked in a SocketChannel read() method and another thread calls the interrupt() method on the first thread, the first thread should return from the blocked read() call after the SocketChannel has been closed, and the second thread should immediately return from the interrupt call no matter what the state of the first thread.
    What's actually happening is that the second thread is locking up in the interrupt() call and the first thread is not returning from the read() call. I'm not sure if I'm missing anything here, but I've not seen any forum discussions or bug reports on this.
    Can anyone shed some light on this behavior? The following demonstration code shows this thread shutdown behavior in two modes:
    No arguments simply spins a thread that uses sleep() to display a line every second. This shuts down as expected.
    Specifying a hostname and port number spins a thread that connects to that address with a SocketChannel and loops on read() calls to that channel. This is what locks up when you try to interrupt() the spun thread.
    Demonstration code JDK1.4.0
    * ThreadExp.java
    * This app works in one of two modes:
    *   1: Invoked with no arguments it will spin a thread that
    *      displays a line every second.
    *   2: Invoked with a hostname and a port number it will spin a thread that
    *      opens a SocketChannel to that address and loops on reading the channel
    *      until it is closed or interrupted.
    * In either case the main thread runs a command interpreter allowing you to:
    *   (return)  Display the threads.
    *   stop      Stop the spun thread.
    *   quit      Quit the application and stop any active thread.
    * This works fine in mode 1, but in mode 2 the main thread locks up in the
    * interrupt() call to the spun thread while the spun thread is blocked in
    * a read() function on the channel. According to the SocketChannel and
    * Thread docs, the call to interrupt() on the spun thread should interrupt
    * the blocked read() call after closing the socket connection. The interrupt
    * call should immediatly return.
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.charset.*;
    import java.net.*;
    public
    class ThreadExp
    implements Runnable {
       private volatile Thread thread = null;
       String hostname;
       int    port;
       public
       ThreadExp(String hostname, int port)
          this.hostname = hostname;
          this.port     = port;
          thread = new Thread(this, "ThreadExpThread");
          thread.start();
       public
       void
       stop()
          if (thread == null) return;
          Thread tmpThread = thread;
          thread = null;
          System.out.println("Interrupting thread...");
          tmpThread.interrupt();
       public
       void
       run()
          Charset        charset = Charset.forName("US-ASCII");
          CharsetDecoder decoder = charset.newDecoder();
          SocketChannel  channel = null;
          ByteBuffer     buf     = ByteBuffer.allocateDirect(1024);
          try {
             if (hostname != null) {
                System.out.println("Opening channel...");
                channel = SocketChannel.open(
                   new InetSocketAddress(InetAddress.getByName(hostname), port)
             Thread thisThread = Thread.currentThread();
             while (thread == thisThread) {
                if (hostname != null) {
                   buf.clear();
                   System.out.println("Reading...");
                   int len = channel.read(buf);
                   System.out.println("Read " + len);
                   if (len < 0) break;
                   buf.flip();
                   System.out.print(decoder.decode(buf));
                } else {
                   System.out.println("  .");
                   thread.sleep(1000);
          } catch (InterruptedException e) {
             System.out.println("Thread interupted.");
          } catch (IOException e) {
             e.printStackTrace();
          } finally {
             if (channel != null) {
                try {
                   System.out.println("Closing channel...");
                   channel.close();
                   channel = null;
                } catch (IOException e) {
                   e.printStackTrace();
          System.out.println("Exiting thread.");
       public static
       void
       main(String args[])
          System.out.println(
               "(return)  Display threads\n"
             + "stop      Stop the spun thread\n"
             + "quit      Quit this app and stop any active thread"
          ThreadExp app = null;
          try {
             if (args.length == 2) {
                app = new ThreadExp(args[0], Integer.parseInt(args[1]));
             } else {
                app = new ThreadExp(null, 0);
             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
             String line;
             while (true) {
                line = in.readLine();
                line.trim();
                line.toLowerCase();
                if (line.length() == 0) {
                   Thread[] threads = new Thread[Thread.activeCount()];
                   int len = Thread.enumerate(threads);
                   System.out.println("Threads:");
                   for (int index = 0; index < len; index++) {
                      System.out.println("  [" + index + "] " + threads[index].getName());
                } else if (line.equals("stop")) {
                   app.stop();
                } else if (line.equals("quit")) break;
          } catch (Exception e) {
             e.printStackTrace();
          if (app != null) app.stop();
    }---------------------------

    (sigh) Apparently I didn't check the "Java Bug Database" box when I did my search for "+SocketChannel +interrupt". Still, not only does this problem not come up in the Forums, but this current topic doesn't come up either. Very strange.
    This problem may be related to bugs #4470470 and/or #4460583. Both were automatically reported by regression suites almost a year ago before most of the 1.4 betas. The report displayed is cryptic and non-specific. The first would seem to relate to a Win32 thread blocked in a SocketChannel.read() not interrupting when another thread closes the socket. The second seems to be a Linux thread blocked on an unspecified SocketChannel call not interrupting when another thread calls interrupt() on the first thread. The evaluations (both dated Oct 2001) on the first talk about Win32 specific behavior when closing a blocked handle, and the second recommends implementing signal based I/O interruption which is supposed to be the reason NIO was written in the first place.
    Is there any way to gain access to these repression tests so that we might better understand what these automated bug reports really mean? It would help a lot in finding if a problem is actually related to that report or not.
    It strikes me as fundamentally strange that these problems should exist and have existed for so long. Signal sensitive blocking/non-blocking sockets have been used for decades and I've got code for all of this in C/C++. Is there any way to find out what the status is on the implementation of the NIO package? The Java Community Process seems to be of no help since they only deal with specifications and not implementations.
    The scalability bug you mentioned is due to a well-known (at least in Win32 circles) limitation of a function that isn't supposed to be used with sockets in the first place. I'm quite confused by this, but without access to that implementation I cannot analyse the algorithm or suggest/submit native code changes. Is there any way to do this?
    I've cobbled a workaround to my problem. It's ugly, not bullet-proof, and context sensitive, but it works for now. Since this is a client application with specific knowledge of the communication protocol traveling through the channel, the interrupt() call in the stop() method can be replaced with a write() call to the channel that will result in the remote host sending a response. The response will unblock the read() call allowing the thread to detect that it has been terminated (Yeee - uck!).
    Demonstration code JDK1.4.0
    ---------------------------import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.charset.*;
    import java.net.*;
    public
    class ThreadExp
    implements Runnable {
       public volatile Thread thread = null;
       String hostname;
       int    port;
       public SocketChannel  channel = null;
       Charset        charset = Charset.forName("US-ASCII");
       CharsetEncoder encoder = charset.newEncoder();
       public
       ThreadExp(String hostname, int port)
          this.hostname = hostname;
          this.port     = port;
          thread = new Thread(this, "ThreadExpThread");
          thread.start();
       public
       void
       stop()
          if (thread == null) return;
          thread = null;
          System.out.println("Stopping thread...");
          try {
             channel.write(encoder.encode(CharBuffer.wrap("\n")));
          } catch (Exception e) {
             e.printStackTrace();
       public
       void
       run()
          CharsetDecoder decoder = charset.newDecoder();
          ByteBuffer     buf     = ByteBuffer.allocateDirect(1024);
          try {
             if (hostname != null) {
                System.out.println("Opening channel...");
                channel = SocketChannel.open(
                   new InetSocketAddress(InetAddress.getByName(hostname), port)
             Thread thisThread = Thread.currentThread();
             while (thread == thisThread) {
                if (hostname != null) {
                   buf.clear();
                   System.out.println("Reading...");
                   int len = channel.read(buf);
                   System.out.println("Read " + len);
                   if (len < 0 || thread != thisThread) break;
                   buf.flip();
                   System.out.print(decoder.decode(buf));
                } else {
                   System.out.println("  .");
                   thread.sleep(1000);
          } catch (InterruptedException e) {
             System.out.println("Thread interupted.");
          } catch (IOException e) {
             e.printStackTrace();
          } finally {
             if (channel != null) {
                try {
                   System.out.println("Closing channel...");
                   channel.close();
                   channel = null;
                } catch (IOException e) {
                   e.printStackTrace();
          System.out.println("Exiting thread.");
       public static
       void
       main(String args[])
          System.out.println(
               "(return)  Display threads\n"
             + "stop      Stop the spun thread\n"
             + "quit      Quit this app and stop any active thread"
          ThreadExp app = null;
          try {
             if (args.length == 2) {
                app = new ThreadExp(args[0], Integer.parseInt(args[1]));
             } else {
                app = new ThreadExp(null, 0);
             BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
             String line;
             while (true) {
                line = in.readLine();
                line.trim();
                line.toLowerCase();
                if (line.length() == 0) {
                   Thread[] threads = new Thread[Thread.activeCount()];
                   int len = Thread.enumerate(threads);
                   System.out.println("Threads:");
                   for (int index = 0; index < len; index++) {
                      System.out.println("  [" + index + "] " + threads[index].getName());
                } else if (line.equals("stop") && app != null) {
                   app.stop();
                   app = null;
                } else if (line.equals("quit")) break;
          } catch (Exception e) {
             e.printStackTrace();
          if (app != null) app.stop();

  • Pl/sql block reading reading table data from single point in time

    I am trying to figure out whether several cursors within a PL/SQL block are executed from within a Single Point In Time, and thus do not see any updates to tables made by other processes or procedures running at the same time.
    The reason I am asking is since I have a block of code making some data extraction, with some initial Sanity Checks before the code executes. However, if some other procedure would be modifying the data in between, then the Sanity Check is invalid. So I am basically trying to figure out if there is some read consistency within a PL/SQL, preventing updates from other processes to be seen.
    Anyone having an idea?.
    BR,
    Cenk

    "Transaction-Level Read Consistency
    Oracle also offers the option of enforcing transaction-level read consistency. When a transaction runs in serializable mode, all data accesses reflect the state of the database as of the time the transaction began. *This means that the data seen by all queries within the same transaction is consistent with respect to a single point in time, except that queries made by a serializable transaction do see changes made by the transaction itself*. Transaction-level read consistency produces repeatable reads and does not expose a query to phantoms."
    http://www.oracle.com/pls/db102/search?remark=quick_search&word=read+consistency&tab_id=&format=ranked

  • How to block reading in "read commited"?

    I wrote following code in my sp:
    select id into tempflag from table where conditions....
    if tempflag is null then
    insert xx into table
    else
    do something else
    end if;
    commit;
    Now let's assume this sp is excuted 2 times at almost same time, 1st transaction has inserted data but not commited yet, and 2nd transaction still not able to read the new inserted data, so it inserted data again. The result is I got 2 data in table, which is what I don't want to see.
    What I want is, when 1st transaction not commited yet, 2nd transaction should be blocking at the select statement, this should prevent the second time inserting.
    Actually this is the default behavior in MSSqlserver(read commited), but I found it quite different in Oracle.
    So how can I implement the above idea? Or any other better solutions? I'm new to Oracle.

    874717 wrote:
    I wrote following code in my sp:
    select id into tempflag from table where conditions....
    if tempflag is null then
    insert xx into table
    else
    do something else
    end if;
    commit;
    Now let's assume this sp is excuted 2 times at almost same time, 1st transaction has inserted data but not commited yet, and 2nd transaction still not able to read the new inserted data, so it inserted data again. The result is I got 2 data in table, which is what I don't want to see.
    What I want is, when 1st transaction not commited yet, 2nd transaction should be blocking at the select statement, this should prevent the second time inserting.
    Actually this is the default behavior in MSSqlserver(read commited), but I found it quite different in Oracle.
    So how can I implement the above idea? Or any other better solutions? I'm new to Oracle.Just put a unique constraint in ID column of your table. I guess that will do the job for you.
    Following piece of code is not necessory
    select id into tempflag from table where conditions....
    if tempflag is null thenDont try to select the table and check if the ID already exist. Just have a unique constraint defined and perform your insert.

  • Native method for reading of linux fifo

    Anyone khow how to use c function (read/wite fifo) with java

    This example shows that a fifo (named pipe) can be used in a FileOutputStream and a FileInputStream:
    import java.io.*;
    public class a {
            public static void main(String args[]) {
                    try     {
                            main0(args);
                    catch (Exception e) {
                            e.printStackTrace();
            public static void main0(String args[]) throws Exception {
                    boolean input=args.length==2;
                    if (input) {
                            InputStream is=new FileInputStream(args[0]);
                            int c;
                            while((c=is.read()) != -1) System.out.print((char)c);
                            is.close();
                            return;
                    OutputStream os=new FileOutputStream(args[0]);
                    for(int i='a';i<='z';i++) os.write(i);
                    os.close();
    }posman@linux:~/ivan> javac a.java
    posman@linux:~/ivan> mkfifo fifo
    posman@linux:~/ivan> file fifo
    fifo: fifo (named pipe)
    posman@linux:~/ivan> java a fifo a &
    [1] 9696
    posman@linux:~/ivan> java a fifo &
    [2] 9704
    posman@linux:~/ivan> abcdefghijklmnopqrstuvwxyz
    [1]- Done java a fifo a
    [2]+ Done java a fifo

  • Want to block reading

    Hi
    I have to find max value from a table and
    insert max+1 into a table.
    how can i block others sessions (may be exe. same query) from reading the table
    while this query is executed.

    I have to get (lowest missing value) from a table tab1 like :
    tab1(col1 number) , col1 contains some numbers with missing values in bet.
    query to find min value missing:
    select min(a.col1) min_value
    from tab1 a,tab1 b
    where a.col1+1=b.col1(+)
    and b.col1 is null
    i will insert into the same table Tab1 min_value+1.
    ideally i should not get duplicate values.
    but when the query is executed thru different sessions , i am finding dup. vals....
    So i suppose reading should be bloked for any session executing this query until i find the min value from tab1 and insert the new value(min+1) inside the table same Tab1 and commit.
    Help..
    Thanks in adv...
    Message was edited by:
    [email protected]

  • Non-blocking read from an InputStream??

    Hello all, I have a bit of a problem. I have a GUI based app that, through the mindterm SSH classes, runs a "tail -f /var/log/somelog" command on a *nix server. The purpose of the app is to make looking through the log's easier for the non-computer lay-person. The problem is that if they click the stop button to stop the output of the tail it doesn't actually stop that thread until the next line is appended to the end of the log file. That could be a second or an hour. So what I need is a way to somehow stop that tail -f command when the user hits stop and not have to wait for the read to occur.
    What I'm working with is a com.mindbright.util.InputStreamPipe that is a subclass of java.io.InputStream. I've tried several things. Such as the seda.nbio.NonblockingInputStream which gives me a runtime classCastException when trying to cast the com.mindbright.util.InputStreamPipe to a seda.nbio.NonblockingInputStream. I've tried creating a java.nio.channels.ReadableByteChannel and using it's read method but that also blocks.
    So my question is, does anyone have any clever solutions to this particular problem? I thought the way to beat it was to find some mechanism to do a read that will just get passed by if there's nothing to read then have it wait an arbitrary amount of time before reading again. So the longest the user would have to wait would be that arbitrary amount of time. But I don't know how to implement this or if it's even a good way to do it.
    Thanks in advance!

    Thanks for the help dubwai. I actually found a way to accomplish this without any non-blocking balony.
    public void run () {
                            try {
                                    java.io.InputStream is = tbs.getConsoleOut();
                                    java.io.BufferedReader in = new java.io.BufferedReader(new java.io.InputStreamReader(is));
                                    String line = null;
                                    // continue is a volatile boolean that gets set to false when user clicks stop
                                    while ( cont ) {
                                            if ( is.available() > 0 ) {
                                                    line = in.readLine();
                                                    System.out.println("in while: "+line);
                                            } // end
                                            else {
                                                    try {
                                                            java.lang.Thread.sleep(500);
    } // end try
                                                    catch ( java.lang.InterruptedException ie ) {
                                                            System.err.println("Error sleeping: "+ie);
                                                    } // end catch
                                            } // end else
                                    } // end while
                                    is.close(); in.close();
                                    System.out.println("After while");
                                    System.exit(0);
                            } // end try
                            catch ( Exception e ) {
                                    System.err.println("Error reading lines: "+e);
                            } // end catch
                    } // end runThis seems to work on a few trial runs.. Does anyone see any possible random timing issues from this??

  • NIO SocketChannel non-blocking read

    Hello.
    I'm not sure a resembling message has already been posted in a forum. In such a case, thanks for redirecting to it.
    Goals :
    A selector is used by a main server thread to make accept and read operations non-blocking.
    When a connection is accepted, the newly created socket channel is configured as non-blocking, and a key is added to the selector with the OP_READ flag.
    When data are available on sockets, a new task (runnable) is created and submitted to a thread pool.
    When a thread is ready to process the request, a pre-allocated bytebuffer is used to read arriving data.
    The problem :
    When the bytebuffer capacity is less than the received bytes count, the read method on the socket channel interrupts the selector on the same selection key. In response to this event, a new task is initiated, interferring with the previous one.
    As expected according to my concurrency policy (ie. with a pool of threads), several requests are processed by parallel threads. To avoid unsafe accesses, i added a synchronized statement on the channel blocking lock, and it seems to works fine. But a better way should exist...
    Questions :
    Is this the expected behavior ?
    Is there any other way to read received data with a small buffer ?
    The full copy of the source code :
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.nio.charset.*;
    import java.net.*;
    import java.util.*;
    import net.moon.threads.*;
    public class Nio1 {
         static class Request {
              boolean isCompleted = false;
              int inputs = 0;
              Set workers = new HashSet();
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              byte p = 0;
              boolean isCompleted() {
                   return isCompleted;
              void countInput() {
                   inputs++;
              void append(final ByteBuffer byteBuffer) {
                   if (isCompleted)
                        throw new IllegalStateException("Request is already completed");
                   workers.add(Thread.currentThread());
                   while (byteBuffer.hasRemaining()) {
                        byte b = byteBuffer.get();
                        baos.write(b);
                        if ((b == '\r') && (p == '\n'))
                             isCompleted = true;
                        p = b;
              int inputs() {
                   return inputs;
              Thread[] workers() {
                   return (Thread[]) workers.toArray(new Thread[0]);
              int size() {
                   return baos.size();
              byte[] getData() {
                   return baos.toByteArray();
              void reset() {
                   isCompleted = false;
                   inputs = 0;
                   baos.reset();
                   workers.clear();
         static private class RequestTask implements Runnable {
         private final static Charset charset = Charset.forName("US-ASCII");
              private final Server server;
              private final SelectionKey selectionKey;
              RequestTask(final Server server, final SelectionKey selectionKey) {
                   this.server = server;
                   this.selectionKey = selectionKey;
              public void run() {
                   log("*** Processing input...");
                   try {
                        SocketChannel channel = (SocketChannel) selectionKey.channel();
    synchronized(channel.blockingLock()) {
                        Request request = (Request) selectionKey.attachment();
                        request.countInput();
                        State state = getState();
                        log("Reading first...");
                        int c = channel.read(state.byteBuffer);
                        log("... Read first : " + c);
                        if (c > 0) {
                             for(;;) {
                                  state.byteBuffer.flip();
                             request.append(state.byteBuffer);
                                  state.byteBuffer.clear();
                                  if (c < state.byteBuffer.capacity()) break;
                                  log("Reading next...");
                                  c = channel.read(state.byteBuffer);
                                  log("... Read next : " + c);
                                  if (c <= 0) break;
                             if (request.isCompleted()) {
                                  log("Request completed : " + request.inputs());
                                  StringBuffer bodyBuffer = new StringBuffer();
                                  bodyBuffer.append("-----------------------------\r\n");
                                  bodyBuffer.append("Request processed in " + request.inputs() + " inputs\r\n");
                                  bodyBuffer.append("Request size is " + request.size() + " bytes\r\n");
                                  bodyBuffer.append("Participating workers :\r\n");
                                  Thread[] workers = request.workers();
                                  for (int i = 0; i < workers.length; i++)
                                       bodyBuffer.append(" * " + workers[i] + "\r\n");
                                  bodyBuffer.append("-----------------------------\r\n");
                                  StringBuffer headerBuffer = new StringBuffer();
                                  headerBuffer.append("HTTP/1.1 200 OK\r\n");
                                  headerBuffer.append("Server: NIO Server 1\r\n");
                                  headerBuffer.append("Content-Type: text/plain\r\n");
                                  headerBuffer.append("Content-Length: ").append(request.size() + bodyBuffer.length()).append("\r\n");
                                  headerBuffer.append("\r\n");
                             CharsetEncoder encoder = charset.newEncoder();
                                  channel.write(encoder.encode(CharBuffer.wrap(headerBuffer)));
                                  channel.write(encoder.encode(CharBuffer.wrap(bodyBuffer)));
                                  channel.write(ByteBuffer.wrap(request.getData()));
                                  request.reset();
                        if (c < 0) {
                             selectionKey.attach(null);
                             selectionKey.cancel();
                             log("!!! Connection terminated for channel " + channel);
                   catch(final Exception x) {
                        x.printStackTrace();
                   log("*** Request processed...");
              private State getState() {
                   State state = (State) server.taskManager.getCurrentWorkerState();
                   if (state == null) {
                        state = new State();
                        server.taskManager.setCurrentWorkerState(state);
                   else {
                        state.byteBuffer.clear();
                   return state;
              private void log(final String text) {
                   System.out.println(Thread.currentThread() + " : " + text);
              static class State {
                   ByteBuffer byteBuffer = ByteBuffer.allocateDirect(32);
         static private class Server implements Runnable {
              private final int port;
              private Thread worker;
              private FIFOTaskManager taskManager;
              Server(final int port) {
                   this.port = port;
                   worker = null;
              synchronized void start() throws Exception {
                   if (worker == null) {
                        log("Starting the server...");
                        taskManager = new FIFOTaskManager("Nio1Workers", 24);
                        worker = new Thread(this);
                        worker.start();
                        synchronized(worker) {
                             try {
                                  worker.wait();
                             catch(InterruptedException x) {
                        log("Server started !");
              public void run() {
                   try {
                        log("Server is starting...");
                        Selector selector = SelectorProvider.provider().openSelector();
                        log("Creating listener on port " + port);
                        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
                        serverSocketChannel.configureBlocking(false);
                        InetSocketAddress inetSocketAddress = new InetSocketAddress(port);
                        serverSocketChannel.socket().bind(inetSocketAddress);
                        SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
                        synchronized(worker) {
                             worker.notify();
                        while (selector.select() >= 0) {
                             Set readyKeys = selector.selectedKeys();
                             log("Keys are ready : " + readyKeys.size());
                             for (Iterator i = readyKeys.iterator(); i.hasNext(); ) {
                                  SelectionKey selectedKey = (SelectionKey) i.next();
                                  if (selectedKey.isAcceptable()) {
                                       ServerSocketChannel ssc = (ServerSocketChannel) selectedKey.channel();
                                       SocketChannel sc = ssc.accept();
                                       sc.configureBlocking(false);
                                       SelectionKey sk = sc.register(selector, SelectionKey.OP_READ);
                                       sk.attach(new Request());
                                       log("Connection accepted for channel " + sc);
                                  else if (selectedKey.isReadable()) {
                                       log("Key ready for input : " + selectedKey);
                                       taskManager.execute(new RequestTask(this, selectedKey));
                                  i.remove();
                             readyKeys = null;
                        log("Server loop interrupted !");
                   catch(Exception x) {
                        x.printStackTrace();
              private void log(final String text) {
                   System.out.println("SERVER: " + text);
         public static void main(final String[] args) throws Exception {
              Server server = new Server(9001);
              server.start();

    Thanks for the trick. I hope the code will be more readable than my sockets !
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.nio.charset.*;
    import java.net.*;
    import java.util.*;
    import net.moon.threads.*;
    public class Nio1 {
         static class Request {
              boolean isCompleted = false;
              int inputs = 0;
              Set workers = new HashSet();
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              byte p = 0;
              boolean isCompleted() {
                   return isCompleted;
              void countInput() {
                   inputs++;
              void append(final ByteBuffer byteBuffer) {
                   if (isCompleted)
                        throw new IllegalStateException("Request is already completed");
                   workers.add(Thread.currentThread());
                   while (byteBuffer.hasRemaining()) {
                        byte b = byteBuffer.get();
                        baos.write(b);
                        if ((b == '\r') && (p == '\n'))
                             isCompleted = true;
                        p = b;
              int inputs() {
                   return inputs;
              Thread[] workers() {
                   return (Thread[]) workers.toArray(new Thread[0]);
              int size() {
                   return baos.size();
              byte[] getData() {
                   return baos.toByteArray();
              void reset() {
                   isCompleted = false;
                   inputs = 0;
                   baos.reset();
                   workers.clear();
         static private class RequestTask implements Runnable {
             private final static Charset charset = Charset.forName("US-ASCII");
              private final Server server;
              private final SelectionKey selectionKey;
              RequestTask(final Server server, final SelectionKey selectionKey) {
                   this.server = server;
                   this.selectionKey = selectionKey;
              public void run() {
                   log("*** Processing input...");
                   try {
                        SocketChannel channel = (SocketChannel) selectionKey.channel();
    synchronized(channel.blockingLock()) {
                        Request request = (Request) selectionKey.attachment();
                        request.countInput();
                        State state = getState();
                        log("Reading first...");
                        int c = channel.read(state.byteBuffer);
                        log("... Read first : " + c);
                        if (c > 0) {
                             for(;;) {
                                  state.byteBuffer.flip();
                                 request.append(state.byteBuffer);
                                  state.byteBuffer.clear();
                                  if (c < state.byteBuffer.capacity()) break;
                                  log("Reading next...");
                                  c = channel.read(state.byteBuffer);
                                  log("... Read next : " + c);
                                  if (c <= 0) break;
                             if (request.isCompleted()) {
                                  log("Request completed : " + request.inputs());
                                  StringBuffer bodyBuffer = new StringBuffer();
                                  bodyBuffer.append("-----------------------------\r\n");
                                  bodyBuffer.append("Request processed in " + request.inputs() + " inputs\r\n");
                                  bodyBuffer.append("Request size is " + request.size() + " bytes\r\n");
                                  bodyBuffer.append("Participating workers :\r\n");
                                  Thread[] workers = request.workers();
                                  for (int i = 0; i < workers.length; i++)
                                       bodyBuffer.append(" * " + workers[i] + "\r\n");
                                  bodyBuffer.append("-----------------------------\r\n");
                                  StringBuffer headerBuffer = new StringBuffer();
                                  headerBuffer.append("HTTP/1.1 200 OK\r\n");
                                  headerBuffer.append("Server: NIO Server 1\r\n");
                                  headerBuffer.append("Content-Type: text/plain\r\n");
                                  headerBuffer.append("Content-Length: ").append(request.size() + bodyBuffer.length()).append("\r\n");
                                  headerBuffer.append("\r\n");
                                 CharsetEncoder encoder = charset.newEncoder();
                                  channel.write(encoder.encode(CharBuffer.wrap(headerBuffer)));
                                  channel.write(encoder.encode(CharBuffer.wrap(bodyBuffer)));
                                  channel.write(ByteBuffer.wrap(request.getData()));
                                  request.reset();
                        if (c < 0) {
                             selectionKey.attach(null);
                             selectionKey.cancel();
                             log("!!! Connection terminated for channel " + channel);
                   catch(final Exception x) {
                        x.printStackTrace();
                   log("*** Request processed...");
              private State getState() {
                   State state = (State) server.taskManager.getCurrentWorkerState();
                   if (state == null) {
                        state = new State();
                        server.taskManager.setCurrentWorkerState(state);
                   else {
                        state.byteBuffer.clear();
                   return state;
              private void log(final String text) {
                   System.out.println(Thread.currentThread() + " : " + text);
              static class State {
                   ByteBuffer byteBuffer = ByteBuffer.allocateDirect(32);
         static private class Server implements Runnable {
              private final int port;
              private Thread worker;
              private FIFOTaskManager taskManager;
              Server(final int port) {
                   this.port = port;
                   worker = null;
              synchronized void start() throws Exception {
                   if (worker == null) {
                        log("Starting the server...");
                        taskManager = new FIFOTaskManager("Nio1Workers", 24);
                        worker = new Thread(this);
                        worker.start();
                        synchronized(worker) {
                             try {
                                  worker.wait();
                             catch(InterruptedException x) {
                        log("Server started !");
              public void run() {
                   try {
                        log("Server is starting...");
                        Selector selector = SelectorProvider.provider().openSelector();
                        log("Creating listener on port " + port);
                        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
                        serverSocketChannel.configureBlocking(false);
                        InetSocketAddress inetSocketAddress = new InetSocketAddress(port);
                        serverSocketChannel.socket().bind(inetSocketAddress);
                        SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
                        synchronized(worker) {
                             worker.notify();
                        while (selector.select() >= 0) {
                             Set readyKeys = selector.selectedKeys();
                             log("Keys are ready : " + readyKeys.size());
                             for (Iterator i = readyKeys.iterator(); i.hasNext(); ) {
                                  SelectionKey selectedKey = (SelectionKey) i.next();
                                  if (selectedKey.isAcceptable()) {
                                       ServerSocketChannel ssc = (ServerSocketChannel) selectedKey.channel();
                                       SocketChannel sc = ssc.accept();
                                       sc.configureBlocking(false);
                                       SelectionKey sk = sc.register(selector, SelectionKey.OP_READ);
                                       sk.attach(new Request());
                                       log("Connection accepted for channel " + sc);
                                  else if (selectedKey.isReadable()) {
                                       log("Key ready for input : " + selectedKey);
                                       taskManager.execute(new RequestTask(this, selectedKey));
                                  i.remove();
                             readyKeys = null;
                        log("Server loop interrupted !");
                   catch(Exception x) {
                        x.printStackTrace();
              private void log(final String text) {
                   System.out.println("SERVER: " + text);
         public static void main(final String[] args) throws Exception {
              Server server = new Server(9001);
              server.start();
    }

  • Stop blocking read from a socket but still preserve it

    Hello, I have a thread waiting for a socket input...in case I wanted to stop it I need a way to stop blocking receive, but not something like close() or shutdownInput() because I don't want to close the socket but simply shut down the thread...any ideas?

    It sounds like you need to set a socket read timeout: see Socket.setSoTimeout(), but exiting the thread and leaving the socket to another thread doesn't sound right. Normally the thread is dedicated to looking after that socket.

  • Blocking reading object from stream

    I have a thread that continually reads objects from the input stream, so I use the readObject() method. My problem is that it doesn't block when there is no input. it just throws exceptions and I cant find a way to check first if there's anything output from the other side of the stream so do a check. thank you!

    Sorry! My mistake! I was confused!

  • Main Volume blocked (read-only permissions)

    Hey,
    I have blocked my main volume for mistake, and now i can't unblock it.... could you please help me?
    My current permissions on volume:
    lrwxr-xr-x l root admin 1 Oct 12 21:05 /volumes/Mac --> /
    I was trying to unblock it on my own:
    sudo chflags 0 /volumes/*
    sudo chmod a+rx /volumes/*
    chmod: Unable to change file mode on /volumes/Mac : Read-only file system
    chmod go= /volumes/*
    chmod: Unable to change file mode on /volumes/Mac : Read-only file system
    chmod go-w,a+x /volumes/*
    chmod: Unable to change file mode on /volumes/Mac : Read-only file system
    Thx in advance
    - mstolarz

    Ok I've just worked out that 'You can only read' is referring to the fact that I can only view permissions but not add any. Below this statement, no permissions are listed which may explain why I cannot access the files but does not explain why I can copy/access some files, also with no permissions...

Maybe you are looking for

  • Advice needed please

    Hello there, New to the forum and cannot find help anywhere else. I have lost the calculator software and cannot reinstall/retrieve it. Also, any software I try to install doesn't work - HotSync stops and says the application wasn't responding to Hot

  • Windows installer engine error when installing LV 8.2.1

    Trying to install LabView 8.2.1 on a system and getting a "Window Installer Engine" error and the program quits.  The software successfully installed on another system. I have disabled all other programs and virus scanners.  Any suggestions? Thank yo

  • Database setup with MySQL and PHP question

    Hello all, I recently had a problem getting a report to work for a site I was updating.  This site is written in PHP with a MySQL database.  The application is to track customer calls to auto repair stores.  The database has a lot of foreign keys bec

  • Transformation XML problem.

    Hello! I have very easy java code for transform XML document (sorry, for print out XML without changes): parser = new DOMParser(); parser.setPreserveWhitespace(false); // parser input XML file xmlURL = createURL(args[0]); parser.parse(xmlURL); xml =

  • Correct way to load Logic

    Dear Forum: Since I should be recieving a MacPro and Logic8 shortly, I'd like to understand the correct method to install Logic. Since I don't have a clear understanding on this, as you'll see, please make any corrections. Initially, I will have thre