Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4887178
Votes 0
Synopsis in with J2se1.3 in multithread situation, socket reads data unexpectly
Category java:classes_net
Reported Against 1.3.1
Release Fixed 1.3.1_11, 1.4.1_07(Bug ID:2071745) , 1.4.2_04(Bug ID:2071746) , 1.5(tiger-b28) (Bug ID:2071747)
State 10-Fix Delivered, Verified, bug
Priority: 3-Medium
Related Bugs
Submit Date 08-JUL-2003
Description
escalationID is 547065
My ISV experiences the below problem as below

testcase is in SocketBug.jar
start server from ost.ServerSimulator
start client from ost.ClientSimuator

BUG : in multithreads situation, socket improperly reads data instead of 
blocking read or throw exceptions, although lock is designed properly.
 
Platform: J2SE1.3
                         
Senario:
The bug is reproducible only with the setSOtimeout ,without an setSOtimeout 
there is no problem


First ServerSimulator  Threads generate many sockets in server side, pass those 
sockets to SocketReader Threads  and put SocketReaders  to a thread pool for 
reading 
also pass those sockets to  SocketCloser threads groups for closing sockets by 
putting socketcloser threads into a same threadpool  and ServerSimuator Threads  
group will also setSoTimeout  for every
passed socket  , SocketReader thread read data from  inputstream completely, it 
will notfiy SocketCloser  thread to close this socket, then it trys to read 4 
bytes data again . at this moment
it should block at  p = in.read(data, 0, 4), because client doesnot send data 
again.
At this moment, socket could be closed or still open, if socket is closed by 
SocketCloser , then IOException should happen at p=in.read(data,0,4). if 
blocking time  expired, then also IOException will 
happen at p=in.read(data,0,4), but SocketReader should never be able to read any 
data at in.read(data,0,0,4), but in multi threads situation, it does read data 
unexpectedly.
Work Around
N/A
Evaluation
I modified the testcase to read 3 bytes in the second read() so as to distinguish the two 'read's. I analysed the system level calls made by the testcase using 'truss'. This is what is happening at the system level:

1336/11:        read(83, "\0010203", 4)                         = 4
...
1336/13:        close(83)                                       = 0
...
1336/6:         accept(6, 0xEE58153C, 0xEE58154C, 1)            = 83
...
1336/11:        read(83, "\00102", 3)                           = 3

Thread 11 reads 4 bytes in the first read call on the socket with fd 83 and notifies other thread to close this socket and proceeds to read 3 more bytes. Meanwhile Thread 13 closes that fd and creates another socket with same fd. Now Thread 11 reads 3 bytes on fd 83 as this is the first read after creation of fd 83 again. 

SocketInputStream class has an instance variable 'impl' of type PlainSocketImpl which contains an instance variable of type FileDescriptor (fd). SocketInputStream has methods to read and close the stream which in turn call the impl's methods to get the fd in read and set the fd to null in close.

Now here what could be happening is: While one thread is in the second read blocked at timeout, another thread closes the stream and sets the 'fd' of PlainSocketImpl to NULL and one another thread creates one more socket with the same file descriptor. Now when the first thread comes out from timeout(in the native), it does not know that the stream has been closed an it passes the old fd number to system read(). As this fd is valid (because it got recreated), read succeeds.

So the native call SocketRead() in SocketInputStream class and the close() method should be synchronized blocks. While one thread is in native SocketRead(), we should not allow other threads to close the stream and set fd to null. 


  xxxxx@xxxxx   2003-07-28
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang