rollback -r1403, which was leading to tmp == p->TLS assertion failures

This commit is contained in:
Sears Russell 2010-09-02 17:59:00 +00:00
parent 00e474e3fe
commit e6067ae60b

View file

@ -70,7 +70,8 @@ static inline int needFlush(stasis_buffer_manager_t * bm) {
static int chWriteBackPage_helper(stasis_buffer_manager_t* bm, pageid_t pageid, int is_hint) { static int chWriteBackPage_helper(stasis_buffer_manager_t* bm, pageid_t pageid, int is_hint) {
stasis_buffer_concurrent_hash_t *ch = bm->impl; stasis_buffer_concurrent_hash_t *ch = bm->impl;
Page * p = hashtable_lookup(ch->ht, pageid/*, &h*/); hashtable_bucket_handle_t h;
Page * p = hashtable_lookup_lock(ch->ht, pageid, &h);
int ret = 0; int ret = 0;
if(!p) { if(!p) {
ret = ENOENT; ret = ENOENT;
@ -80,32 +81,15 @@ static int chWriteBackPage_helper(stasis_buffer_manager_t* bm, pageid_t pageid,
ret = EBUSY; ret = EBUSY;
p->needsFlush = 1; // Not atomic. Oh well. p->needsFlush = 1; // Not atomic. Oh well.
} }
if(p->id != pageid) { // it must have been written back...
unlock(p->loadlatch);
return 0;
}
} else { } else {
// Uggh. With the current design, it's possible that the trywritelock will block on the writeback thread. // Uggh. With the current design, it's possible that the trywritelock will block on the writeback thread.
// That leaves us with few options, so we expose two sets of semantics up to the caller. // That leaves us with few options, so we expose two sets of semantics up to the caller.
// This used to call writelock while holding a hashtable bucket lock, risking deadlock if called when the page was pinned. // Since this isn't a hint, the page is not pinned. Therefore, the following will only deadlock if the caller is buggy.
// We could assume that the caller knows what it's doing, and writeback regardless of whether the page is
// pinned. This could allow torn pages to reach disk, and would risk calling page compaction, etc while the
// page is concurrently read. However, it would prevent us from blocking on application pins. Unfortunately,
// compacting under during application reads is a deal breaker.
// Instead, we release the hashtable lock, get the write latch, then double check the pageid.
// This is safe, since we know that page pointers are never freed, only reused. However, it causes writeback
// to block waiting for application threads to unpin their pages.
writelock(p->loadlatch,0); writelock(p->loadlatch,0);
if(p->id != pageid) {
// someone else wrote it back. woohoo.
unlock(p->loadlatch);
return 0;
}
} }
} }
hashtable_unlock(&h);
if(ret) { return ret; } if(ret) { return ret; }
// write calls stasis_page_flushed(p); // write calls stasis_page_flushed(p);
ch->page_handle->write(ch->page_handle, p); ch->page_handle->write(ch->page_handle, p);