avoid r/w lock deadlock by finishing read lock before proceeding with exception handling that needs write lock

This commit is contained in:
Maxim.Mossienko
2012-06-29 23:11:23 +04:00
parent 0cc35ba8b4
commit c593c63814
@@ -758,64 +758,69 @@ public class FSRecords implements Forceable {
public static int[] list(int id) {
try {
r.lock();
final DataInputStream input = readAttribute(id, CHILDREN_ATT);
if (input == null) return ArrayUtil.EMPTY_INT_ARRAY;
try {
final DataInputStream input = readAttribute(id, CHILDREN_ATT);
if (input == null) return ArrayUtil.EMPTY_INT_ARRAY;
final int count = DataInputOutputUtil.readINT(input);
final int[] result = ArrayUtil.newIntArray(count);
for (int i = 0; i < count; i++) {
int childId = DataInputOutputUtil.readINT(input);
childId = childId >= 0 ? childId + id : -childId;
result[i] = childId;
final int count = DataInputOutputUtil.readINT(input);
final int[] result = ArrayUtil.newIntArray(count);
for (int i = 0; i < count; i++) {
int childId = DataInputOutputUtil.readINT(input);
childId = childId >= 0 ? childId + id : -childId;
result[i] = childId;
}
input.close();
return result;
}
finally {
r.unlock();
}
input.close();
return result;
}
catch (Throwable e) {
throw DbConnection.handleError(e);
}
finally {
r.unlock();
}
}
public static Pair<String[],int[]> listAll(int parentId) {
try {
r.lock();
final DataInputStream input = readAttribute(parentId, CHILDREN_ATT);
if (input == null) return Pair.create(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_INT_ARRAY);
try {
final DataInputStream input = readAttribute(parentId, CHILDREN_ATT);
if (input == null) return Pair.create(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_INT_ARRAY);
final int count = DataInputOutputUtil.readINT(input);
final int[] ids = ArrayUtil.newIntArray(count);
final String[] names = ArrayUtil.newStringArray(count);
for (int i = 0; i < count; i++) {
int id = DataInputOutputUtil.readINT(input);
id = id >= 0 ? id + parentId : -id;
ids[i] = id;
names[i] = getName(id);
final int count = DataInputOutputUtil.readINT(input);
final int[] ids = ArrayUtil.newIntArray(count);
final String[] names = ArrayUtil.newStringArray(count);
for (int i = 0; i < count; i++) {
int id = DataInputOutputUtil.readINT(input);
id = id >= 0 ? id + parentId : -id;
ids[i] = id;
names[i] = getName(id);
}
input.close();
return Pair.create(names, ids);
}
finally {
r.unlock();
}
input.close();
return Pair.create(names, ids);
}
catch (Throwable e) {
throw DbConnection.handleError(e);
}
finally {
r.unlock();
}
}
public static boolean wereChildrenAccessed(int id) {
try {
r.lock();
return findAttributePage(id, CHILDREN_ATT, false) != 0;
try {
return findAttributePage(id, CHILDREN_ATT, false) != 0;
} finally {
r.unlock();
}
}
catch (Throwable e) {
throw DbConnection.handleError(e);
}
finally {
r.unlock();
}
}
public static void updateList(int id, int[] children) {
@@ -873,20 +878,22 @@ public class FSRecords implements Forceable {
public static int getParent(int id) {
try {
r.lock();
final int parentId = getRecordInt(id, PARENT_OFFSET);
if (parentId == id) {
LOG.error("Cyclic parent child relations in the database. id = " + id);
return 0;
}
try {
final int parentId = getRecordInt(id, PARENT_OFFSET);
if (parentId == id) {
LOG.error("Cyclic parent child relations in the database. id = " + id);
return 0;
}
return parentId;
return parentId;
}
finally {
r.unlock();
}
}
catch (Throwable e) {
throw DbConnection.handleError(e);
}
finally {
r.unlock();
}
}
public static void setParent(int id, int parent) {
@@ -911,15 +918,17 @@ public class FSRecords implements Forceable {
public static String getName(int id) {
try {
r.lock();
final int nameId = getRecordInt(id, NAME_OFFSET);
return nameId != 0 ? getNames().valueOf(nameId) : "";
try {
final int nameId = getRecordInt(id, NAME_OFFSET);
return nameId != 0 ? getNames().valueOf(nameId) : "";
}
finally {
r.unlock();
}
}
catch (Throwable e) {
throw DbConnection.handleError(e);
}
finally {
r.unlock();
}
}
public static void setName(int id, String name) {
@@ -1195,14 +1204,16 @@ public class FSRecords implements Forceable {
public static int getContentId(int fileId) {
try {
r.lock();
return getContentRecordId(fileId);
try {
return getContentRecordId(fileId);
}
finally {
r.unlock();
}
}
catch (Throwable e) {
throw DbConnection.handleError(e);
}
finally {
r.unlock();
}
}
@NotNull