Начинающий
- Статус
- Оффлайн
- Регистрация
- 5 Июн 2025
- Сообщения
- 500
- Реакции
- 24
Драсте, я уже довольно долго работаю над большим фреймворком пересекающимся с нативными библиотеками, и всё чаще и чаще возникает вопрос касательно неопределенного поведения библиотеки при использовании её "абы как". Что-бы было чуть понятнее - приведу пример:
К примеру у нас есть библиотека для работы которой нужно создавать контекст, но есть какой-то объект который требует для своей работы контекст, но из-за специфики этого объекта и его поведения полностью предостеречь от кривого поведения при исчезновении контекста не получится.
Как пример, представим что это пул объектов(NativeObject) которые создаются в самом контексте, можно при создании пула проверить есть ли контекст, при получении объекта(obtain) и отсутствии свободных оных(NativeObject) в пуле(при создании пулом нового объекта через контекст) можно сделать проверку на существование контекста, но при этом если контекст в моменте теряется, пул сам по себе не пропадает, NativeObject закрепленные за пулом так-же не пропадают (максимум - можно освободить нативные ресурсы NativeObject которыми владеет пул, но это сильно осложнит реализацию самого NativeObject).
При освобождении без проверки контекста можно сильно наебаться и крашнуть JVM нативным вызовом, что не есть хорошо, с проверкой - метод бесполезен. Т.е. при пропаже контекста фактически весь пул становится мусорным объектом который не может функционировать, это тоже не хорошо, но поскольку вкинуть пул в пакет к контексту(в имплементацию а не как доп. функционал из коробки) нельзя(потому-что имплементация фактически закрытая за исключением 1-2 методов) - я в целом хрен знает что с этим можно придумать.
Казалось бы не делает ничего free() и obtain() - ну пусть и не делают, но мне это тоже как-то не внушает доверие что такое можно считать за нормальное поведение кода, поэтому собсна вопрос и запостил, что-бы понять где еще рамки нормы можно натянуть на глобус, а где - тотальный треш
Пример кода:
К примеру у нас есть библиотека для работы которой нужно создавать контекст, но есть какой-то объект который требует для своей работы контекст, но из-за специфики этого объекта и его поведения полностью предостеречь от кривого поведения при исчезновении контекста не получится.
Как пример, представим что это пул объектов(NativeObject) которые создаются в самом контексте, можно при создании пула проверить есть ли контекст, при получении объекта(obtain) и отсутствии свободных оных(NativeObject) в пуле(при создании пулом нового объекта через контекст) можно сделать проверку на существование контекста, но при этом если контекст в моменте теряется, пул сам по себе не пропадает, NativeObject закрепленные за пулом так-же не пропадают (максимум - можно освободить нативные ресурсы NativeObject которыми владеет пул, но это сильно осложнит реализацию самого NativeObject).
При освобождении без проверки контекста можно сильно наебаться и крашнуть JVM нативным вызовом, что не есть хорошо, с проверкой - метод бесполезен. Т.е. при пропаже контекста фактически весь пул становится мусорным объектом который не может функционировать, это тоже не хорошо, но поскольку вкинуть пул в пакет к контексту(в имплементацию а не как доп. функционал из коробки) нельзя(потому-что имплементация фактически закрытая за исключением 1-2 методов) - я в целом хрен знает что с этим можно придумать.
Казалось бы не делает ничего free() и obtain() - ну пусть и не делают, но мне это тоже как-то не внушает доверие что такое можно считать за нормальное поведение кода, поэтому собсна вопрос и запостил, что-бы понять где еще рамки нормы можно натянуть на глобус, а где - тотальный треш
Пример кода:
Проблема:
class NativeObjectPool {
List<NativeObject> obtainedObjects;
List<NativeObject> freeObjects;
ExamplePool(int size) {
checkContext();
obtainedObjects = new List<>(size);
freeObjects = new List<>(size);
}
NativeObject obtain() {
// Если есть свободный объект
if (freeObjects.size() > 0) {
NativeObject obj = freeObjects.remove(0);
obtainedObjects.add(obj);
return obj;
}
// Если свободных объектов нет и нужно его создать
if (!checkSize()) {
return null; // превышен лимит размера
}
checkContext(); // Проверяем существование контекста
NativeObject obj = Context.instance().createNativeObject();
obtainedObjects.add(obj);
return obj;
}
void free(@NotNull NativeObject obj) {
// Проблема тут, проверить контекст мы можем, но что делать если нам вернули такой объект без контекста?
// Если вызвать метод NativeObject#reset() мы можем получить JVM-краш из-за отсутствия нативного контекста
// Просто игнорировать?...
if (contextExists() && obtainedSources.contains(obj)) {
obtainedSources.remove(obj);
obj.reset();
freeSources.add(obj);
}
}
boolean checkSize() { ... }
}