在 The Tools We Work With 中,Varnish软件的作者对新的ISO C标准草案表示失望。特别是他认为应该有一些有用的东西,比如“断言我持有这个互斥锁定”的功能,并且他声称他在Vanish中写了一个。
我查了一下代码。它基本上是这样的:
struct ilck {
unsigned magic;
pthread_mutex_t mtx;
int held;
pthread_t owner;
VTAILQ_ENTRY(ilck) list;
const char *w;
struct VSC_C_lck *stat;
};
void Lck__Lock(struct ilck *ilck, const char *p, const char *f, int l)
{
if (!(params->diag_bitmap & 0x18)) {
AZ(pthread_mutex_lock(&ilck->mtx));
AZ(ilck->held);
ilck->stat->locks++;
ilck->owner = pthread_self();
ilck->held = 1;
return;
}
r = pthread_mutex_trylock(&ilck->mtx);
assert(r == 0 || r == EBUSY);
if (r) {
ilck->stat->colls++;
if (params->diag_bitmap & 0x8)
VSL(SLT_Debug, 0, "MTX_CONTEST(%s,%s,%d,%s)",
p, f, l, ilck->w);
AZ(pthread_mutex_lock(&ilck->mtx));
} else if (params->diag_bitmap & 0x8) {
VSL(SLT_Debug, 0, "MTX_LOCK(%s,%s,%d,%s)", p, f, l, ilck->w);
}
ilck->stat->locks++;
ilck->owner = pthread_self();
ilck->held = 1;
}
void
Lck__Assert(const struct ilck *ilck, int held)
{
if (held)
assert(ilck->held &&
pthread_equal(ilck->owner, pthread_self()));
else
assert(!ilck->held ||
!pthread_equal(ilck->owner, pthread_self()));
}
我省略了try-lock和unlock操作的实现,因为它们基本上是常规的。我有疑问的地方是Lck__Assert(),其中对ilck-> hold和lick->所有者的访问不受任何互斥锁的保护。
所以说下面的事件序列:
在我看来,应该有一些“全局”互斥锁来保护互斥锁自己的数据,或者至少是一些写/读屏障。我的分析是否正确?
答案 0 :(得分:0)
我已联系过作者。他说我的分析是有效的,并使用memset(,0)取消设置“thread_t所有者”,因为thread_t不是具有指定赋值运算符的透明结构。希望适用于大多数平台。