Skip to content

Commit

Permalink
Fix for JDBC-232 : event Thread consumes 100% CPU time after Firebird…
Browse files Browse the repository at this point in the history
… shutdown/crash

+ Improved robustness of closing connection and XdrInputStream / XdrOutputStream
  • Loading branch information
mrotteveel committed Apr 15, 2012
1 parent 80ec055 commit 360187d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 46 deletions.
53 changes: 21 additions & 32 deletions src/main/org/firebirdsql/gds/impl/wire/AbstractJavaGDSImpl.java
Expand Up @@ -3067,9 +3067,6 @@ class EventCoordinatorImp implements EventCoordinator, Runnable {
private int handle;
private String ipAddress;
private int port;
private Socket socket;
private XdrOutputStream out;
private WireXdrInputStream in;
private int eventsId = 0;
isc_db_handle_impl db;
private Map globMap = new HashMap();
Expand Down Expand Up @@ -3143,29 +3140,35 @@ public void run(){
break;
}
}
doClose();
} catch (IOException ioe){
throw new RuntimeException(
"IOException in event loop: " + ioe.getMessage());
} catch (GDSException gdse){
throw new RuntimeException(
"GDSException in event loop: " + gdse.getMessage());
} catch (IOException ioe) {
if (log != null) {
log.fatal("IOException in event loop: " + ioe.getMessage(), ioe);
}
} catch (GDSException gdse) {
if (log != null) {
log.fatal("GDSException in event loop: " + gdse.getMessage(), gdse);
}
} finally {
try {
doClose();
} catch (IOException e) {
if (log != null && log.isDebugEnabled()) {
log.debug("IOException closing event connection", e);
}
}
}
}


/**
* Connect to receive event callbacks
*/
private void connect() throws GDSException {
try {
db = new isc_db_handle_impl();
socket = new Socket(ipAddress, port);
socket.setTcpNoDelay(true);
out = new XdrOutputStream(socket.getOutputStream());
in = new WireXdrInputStream(socket.getInputStream());
db.in = in;
db.out = out;
db.socket = new Socket(ipAddress, port);
db.socket.setTcpNoDelay(true);
db.out = new XdrOutputStream(db.socket.getOutputStream());
db.in = new WireXdrInputStream(db.socket.getInputStream());
} catch (UnknownHostException uhe){
throw new GDSException(
ISCConstants.isc_arg_gds,
Expand All @@ -3184,22 +3187,9 @@ public void close() throws IOException {
}

private void doClose() throws IOException {
if (in != null){
in.close();
in = null;
}
if (out != null){
out.close();
out = null;
}
if (socket != null){
socket.close();
socket = null;
}

db.invalidate();
}


public void queueEvents(isc_db_handle_impl mainDb,
EventHandleImp eventHandle,
EventHandler eventHandler) throws GDSException {
Expand Down Expand Up @@ -3253,7 +3243,6 @@ public EventHandleImp getEventHandle(){
}
}


public void fbCancelOperation(IscDbHandle dbHandle, int kind)
throws GDSException {

Expand Down
11 changes: 8 additions & 3 deletions src/main/org/firebirdsql/gds/impl/wire/XdrInputStream.java
Expand Up @@ -253,6 +253,8 @@ public int read() throws IOException {
int readn = in.read(buf, 0, defaultBufferSize);
if (readn > 0)
count = readn;
else
throw new EOFException();
}
return buf[pos++] & 0xff;
}
Expand All @@ -266,8 +268,11 @@ public int read() throws IOException {
public void close() throws IOException {
if (in == null)
return;
in.close();
in = null;
buf = null;
try {
in.close();
} finally {
in = null;
buf = null;
}
}
}
7 changes: 6 additions & 1 deletion src/main/org/firebirdsql/gds/impl/wire/XdrOutputStream.java
Expand Up @@ -393,7 +393,12 @@ public void flush() throws IOException {
* underlying stream
*/
public void close() throws IOException {
out.close();
try {
out.close();
} finally {
buf = null;
out = null;
}
}


Expand Down
42 changes: 32 additions & 10 deletions src/main/org/firebirdsql/gds/impl/wire/isc_db_handle_impl.java
Expand Up @@ -54,20 +54,42 @@ public isc_db_handle_impl() {
}

protected void invalidate() throws IOException {

if (!isValid())
return;

IOException ioeToThrow = null;

// TODO: Shouldn't this synchronize on *this*?
in.close();
out.close();
socket.close();

in = null;
out = null;
socket = null;

invalidateHandle();
try {
try {
in.close();
} catch (IOException e) {
ioeToThrow = e;
}
try {
out.close();
} catch (IOException e) {
if (ioeToThrow == null) {
ioeToThrow = e;
}
}
try {
socket.close();
} catch (IOException e) {
if (ioeToThrow == null) {
ioeToThrow = e;
}
}
} finally {
in = null;
out = null;
socket = null;

invalidateHandle();
if (ioeToThrow != null) {
throw ioeToThrow;
}
}
}

void addTransaction(isc_tr_handle_impl tr) {
Expand Down

0 comments on commit 360187d

Please sign in to comment.