@@ -104,41 +104,38 @@ impl<IO: Io> SharedWal<IO> {
104104 match tx {
105105 Transaction :: Write ( _) => unreachable ! ( "already in a write transaction" ) ,
106106 Transaction :: Read ( read_tx) => {
107- {
108- let mut reserved = self . wal_lock . reserved . lock ( ) ;
109- match * reserved {
110- // we have already reserved the slot, go ahead and try to acquire
111- Some ( id) if id == read_tx. conn_id => {
112- tracing:: trace!( "taking reserved slot" ) ;
113- reserved. take ( ) ;
114- let lock = self . wal_lock . tx_id . lock_blocking ( ) ;
107+ let mut reserved = self . wal_lock . reserved . lock ( ) ;
108+ match * reserved {
109+ // we have already reserved the slot, go ahead and try to acquire
110+ Some ( id) if id == read_tx. conn_id => {
111+ tracing:: trace!( "taking reserved slot" ) ;
112+ reserved. take ( ) ;
113+ let lock = self . wal_lock . tx_id . lock_blocking ( ) ;
114+ assert ! ( lock. is_none( ) ) ;
115+ let write_tx = self . acquire_write ( read_tx, lock, reserved) ?;
116+ * tx = Transaction :: Write ( write_tx) ;
117+ return Ok ( ( ) ) ;
118+ }
119+ None => {
120+ let lock = self . wal_lock . tx_id . lock_blocking ( ) ;
121+ if lock. is_none ( ) && self . wal_lock . waiters . is_empty ( ) {
115122 let write_tx = self . acquire_write ( read_tx, lock, reserved) ?;
116123 * tx = Transaction :: Write ( write_tx) ;
117124 return Ok ( ( ) ) ;
118125 }
119- _ => ( ) ,
120126 }
127+ _ => ( ) ,
121128 }
122129
123- let lock = self . wal_lock . tx_id . lock_blocking ( ) ;
124- match * lock {
125- None if self . wal_lock . waiters . is_empty ( ) => {
126- let write_tx =
127- self . acquire_write ( read_tx, lock, self . wal_lock . reserved . lock ( ) ) ?;
128- * tx = Transaction :: Write ( write_tx) ;
129- return Ok ( ( ) ) ;
130- }
131- Some ( _) | None => {
132- tracing:: trace!(
133- "txn currently held by another connection, registering to wait queue"
134- ) ;
135- let parker = crossbeam:: sync:: Parker :: new ( ) ;
136- let unparker = parker. unparker ( ) . clone ( ) ;
137- self . wal_lock . waiters . push ( ( unparker, read_tx. conn_id ) ) ;
138- drop ( lock) ;
139- parker. park ( ) ;
140- }
141- }
130+ tracing:: trace!(
131+ "txn currently held by another connection, registering to wait queue"
132+ ) ;
133+
134+ let parker = crossbeam:: sync:: Parker :: new ( ) ;
135+ let unparker = parker. unparker ( ) . clone ( ) ;
136+ self . wal_lock . waiters . push ( ( unparker, read_tx. conn_id ) ) ;
137+ drop ( reserved) ;
138+ parker. park ( ) ;
142139 }
143140 }
144141 }
@@ -150,6 +147,8 @@ impl<IO: Io> SharedWal<IO> {
150147 mut tx_id_lock : async_lock:: MutexGuard < Option < u64 > > ,
151148 mut reserved : MutexGuard < Option < u64 > > ,
152149 ) -> Result < WriteTransaction < IO :: File > > {
150+ assert ! ( reserved. is_none( ) || * reserved == Some ( read_tx. conn_id) ) ;
151+ assert ! ( tx_id_lock. is_none( ) ) ;
153152 // we read two fields in the header. There is no risk that a transaction commit in
154153 // between the two reads because this would require that:
155154 // 1) there would be a running txn
0 commit comments