Skip to content
Snippets Groups Projects
Commit c8b93909 authored by stepan's avatar stepan
Browse files

Fix issue when MAX_CONNECTIONS limit is reached

Remove broken ReferenceQueue with connections, just use WeakReferences. Unclosed connections may still leak resources.
parent 38f17672
No related branches found
No related tags found
No related merge requests found
...@@ -80,11 +80,6 @@ public class ConnectionSupport { ...@@ -80,11 +80,6 @@ public class ConnectionSupport {
*/ */
private int hwm = 2; private int hwm = 2;
/**
* Periodically we can poll the queue and close unused connections as per GnuR.
*/
private final ReferenceQueue<BaseRConnection> refQueue = new ReferenceQueue<>();
private ContextStateImpl() { private ContextStateImpl() {
for (int i = 0; i < MAX_CONNECTIONS; i++) { for (int i = 0; i < MAX_CONNECTIONS; i++) {
allConnections.add(i, null); allConnections.add(i, null);
...@@ -112,8 +107,8 @@ public class ConnectionSupport { ...@@ -112,8 +107,8 @@ public class ConnectionSupport {
} }
private int setConnection(int index, BaseRConnection con) { private int setConnection(int index, BaseRConnection con) {
assert allConnections.get(index) == null; assert allConnections.get(index) == null || allConnections.get(index).get() == null;
allConnections.set(index, new WeakReference<>(con, refQueue)); allConnections.set(index, new WeakReference<>(con));
return index; return index;
} }
...@@ -141,16 +136,30 @@ public class ConnectionSupport { ...@@ -141,16 +136,30 @@ public class ConnectionSupport {
} }
private int setConnection(BaseRConnection con) { private int setConnection(BaseRConnection con) {
collectUnusedConnections(); int i = findEmptySlot(con);
if (i == -1) {
// TODO: rewrite to ReferenceQueue
// We have no way of reclaiming the connection slots than GC...
System.gc();
i = findEmptySlot(con);
}
if (i >= 0) {
return setConnection(i, con);
} else {
throw RError.error(RError.SHOW_CALLER2, RError.Message.ALL_CONNECTIONS_IN_USE);
}
}
private int findEmptySlot(BaseRConnection con) {
for (int i = 3; i < MAX_CONNECTIONS; i++) { for (int i = 3; i < MAX_CONNECTIONS; i++) {
if (allConnections.get(i) == null) { if (allConnections.get(i) == null || allConnections.get(i).get() == null) {
if (i > hwm) { if (i > hwm) {
hwm = i; hwm = i;
} }
return setConnection(i, con); return i;
} }
} }
throw RError.error(RError.SHOW_CALLER2, RError.Message.ALL_CONNECTIONS_IN_USE); return -1;
} }
@Override @Override
...@@ -168,24 +177,6 @@ public class ConnectionSupport { ...@@ -168,24 +177,6 @@ public class ConnectionSupport {
} }
} }
private void collectUnusedConnections() {
while (true) {
Reference<? extends BaseRConnection> ref = refQueue.poll();
if (ref == null) {
return;
}
BaseRConnection con = ref.get();
if (con instanceof TextConnections.TextRConnection) {
RError.warning(RError.SHOW_CALLER2, RError.Message.UNUSED_TEXTCONN, con.descriptor, ((TextConnections.TextRConnection) con).description);
}
if (con != null) {
int index = con.descriptor;
closeAndDestroy(con);
allConnections.set(index, null);
}
}
}
private static void closeAndDestroy(BaseRConnection con) { private static void closeAndDestroy(BaseRConnection con) {
if (!con.closed) { if (!con.closed) {
try { try {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment