Привет, ЛОР. Вопрос, наверное, простой, только никак не могу найти ответ на него. Все форумы облазил, никто не знает.
Короче, дело происходит в ядре линукса. Нужно корректно удалить мутекс. Мутекс создается динамически, через mutex_init(). И весь вопрос в том, как его теперь корректно удалить.
Упрощенный пример:
//somewhere in the code:
typedef struct {
struct mutex *lock;
int ref_count;
} super_duper_mutex_struct;
super_duper_mutex_struct * create_sdms () {
super_duper_mutex_struct * r = kmalloc (sizeof (super_duper_mutex_struct), GFP_KERNEL);
if (r) {
mutex_init(r->lock);
r->ref_count = 1;
}
return r;
}
//in another place
void delete_sdms(super_duper_mutex_struct *r) {
mutex_lock(r->lock);
r->ref_count--;
if (r->ref_count == 0) {
mutex_unlock (r->lock);
mutex_destroy(r->lock);
kfree (r);
} else mutex_unlock(r->lock);
}
В приведенном коде сразу несколько проблем.
- Предположим есть 2 потока. Предположим, поток_1 успешно доходит до mutex_destroy() и пытается удалить мутекс. Поток_2 в это время встал на ожидание в mutex_lock(). Далее, поток_2 видит, что мутекс разблокирован врывается в секцию. Что произойдет далее неизвестно. Либо поток_1 попытается удалить заблокированный мутекс. Либо поток_1 уже удалит мутекс и тогда не понятно, что произойдет с потоком_2, который на этом мутексе висит в ожидании?
- Проблема вторая связана с освобождением памяти, занимаемой структурой. Поток_1 освободит память из-под структуры. Поток_2 ворвется в секцию и попытается уменьшить уже освобожденный реф-каунтер.
Со второй проблемой, я еще могу справиться, как-то по-другому перефразировав код. Но с первой я вообще не понимаю. Как правильно удалить мутекс, если там будут висеть потоки?
Заранее спасибо за ответы, если вдруг кто-нибудь что-то знает на этот счет. :-)