@@ -102,15 +102,6 @@ struct fil_space_t
102102/* * Log sequence number of the latest MLOG_INDEX_LOAD record
103103that was found while parsing the redo log */
104104lsn_t enable_lsn;
105- /* * set when an .ibd file is about to be deleted,
106- or an undo tablespace is about to be truncated.
107- When this is set following new ops are not allowed:
108- * read IO request
109- * ibuf merge
110- * file flush
111- Note that we can still possibly have new write operations
112- because we don't check this flag when doing flush batches. */
113- bool stop_new_ops;
114105/* * whether undo tablespace truncation is in progress */
115106bool is_being_truncated;
116107#ifdef UNIV_DEBUG
@@ -142,14 +133,22 @@ struct fil_space_t
142133ulint n_pending_flushes; /* !< this is positive when flushing
143134the tablespace to disk; dropping of the
144135tablespace is forbidden if this is positive */
145- /* * Number of pending buffer pool operations accessing the tablespace
146- without holding a table lock or dict_sys.latch S-latch
147- that would prevent the table (and tablespace) from being
148- dropped. An example is change buffer merge.
149- The tablespace cannot be dropped while this is nonzero,
150- or while fil_node_t::n_pending is nonzero.
151- Protected by fil_system.mutex and std::atomic. */
152- std::atomic<ulint> n_pending_ops;
136+ private:
137+ /* * Number of pending buffer pool operations accessing the
138+ tablespace without holding a table lock or dict_operation_lock
139+ S-latch that would prevent the table (and tablespace) from being
140+ dropped. An example is change buffer merge.
141+
142+ The tablespace cannot be dropped while this is nonzero, or while
143+ fil_node_t::n_pending is nonzero.
144+
145+ The most significant bit contains the STOP_NEW_OPS flag. */
146+ Atomic_relaxed<size_t > n_pending_ops;
147+
148+ /* * Flag in n_pending_ops that indicates that the tablespace is being
149+ deleted, and no further operations should be performed */
150+ static const size_t STOP_NEW_OPS= ~(~size_t (0 ) >> 1 );
151+ public:
153152/* * Number of pending block read or write operations
154153(when a write is imminent or a read has recently completed).
155154The tablespace object cannot be freed while this is nonzero,
@@ -183,9 +182,6 @@ struct fil_space_t
183182
184183ulint magic_n;/* !< FIL_SPACE_MAGIC_N */
185184
186- /* * @return whether the tablespace is about to be dropped */
187- bool is_stopping () const { return stop_new_ops; }
188-
189185 /* * Clamp a page number for batched I/O, such as read-ahead.
190186 @param offset page number limit
191187 @return offset clamped to the tablespace size */
@@ -270,20 +266,45 @@ struct fil_space_t
270266/* * Close each file. Only invoked on fil_system.temp_space. */
271267void close ();
272268
273- /* * Acquire a tablespace reference. */
274- void acquire () { n_pending_ops++; }
275- /* * Release a tablespace reference.
276- @return whether this was the last reference */
277- bool release () { auto n= n_pending_ops--; ut_ad (n); return n == 1 ; }
278- /* * @return whether references are being held */
279- bool referenced () const { return n_pending_ops; }
280-
281- /* * Acquire a tablespace reference for I/O. */
282- void acquire_for_io () { n_pending_ios++; }
283- /* * Release a tablespace reference for I/O. */
284- void release_for_io () { ut_ad (pending_io ()); n_pending_ios--; }
285- /* * @return whether I/O is pending */
286- bool pending_io () const { return n_pending_ios; }
269+ /* * @return whether the tablespace is about to be dropped */
270+ bool is_stopping () const { return n_pending_ops & STOP_NEW_OPS; }
271+
272+ /* * @return number of references being held */
273+ size_t referenced () const { return n_pending_ops & ~STOP_NEW_OPS; }
274+
275+ /* * Note that operations on the tablespace must stop or can resume */
276+ void set_stopping (bool stopping)
277+ {
278+ ut_d (auto n=) n_pending_ops.fetch_xor (STOP_NEW_OPS);
279+ ut_ad (!(n & STOP_NEW_OPS) == stopping);
280+ }
281+
282+ MY_ATTRIBUTE ((warn_unused_result))
283+ /* * @return whether a tablespace reference was successfully acquired */
284+ bool acquire()
285+ {
286+ size_t n= 0 ;
287+ while (!n_pending_ops.compare_exchange_strong (n, n + 1 ,
288+ std::memory_order_acquire,
289+ std::memory_order_relaxed))
290+ if (UNIV_UNLIKELY (n & STOP_NEW_OPS))
291+ return false ;
292+ return true ;
293+ }
294+ /* * Release a tablespace reference.
295+ @return whether this was the last reference */
296+ bool release ()
297+ {
298+ auto n= n_pending_ops.fetch_sub (1 );
299+ ut_ad (n & ~STOP_NEW_OPS);
300+ return (n & ~STOP_NEW_OPS) == 1 ;
301+ }
302+ /* * Acquire a tablespace reference for I/O. */
303+ void acquire_for_io () { n_pending_ios++; }
304+ /* * Release a tablespace reference for I/O. */
305+ void release_for_io () { ut_d (auto n=) n_pending_ios--; ut_ad (n); }
306+ /* * @return whether I/O is pending */
307+ bool pending_io () const { return n_pending_ios; }
287308#endif /* !UNIV_INNOCHECKSUM */
288309/* * FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
289310check fsp0types.h to more info about flags. */
0 commit comments