@@ -1908,40 +1908,12 @@ impl Downstairs {
1908
1908
}
1909
1909
}
1910
1910
1911
- /*
1912
- * Only grab the lock if the UpstairsConnection matches.
1913
- *
1914
- * Multiple Upstairs connecting to this Downstairs will spawn multiple
1915
- * threads that all can potentially add work to the same `active` hash
1916
- * map. Only one Upstairs can be "active" at any one time though.
1917
- * When promote_to_active takes the work lock, it will clear out the
1918
- * `active` hash map and (if applicable) will signal to the currently
1919
- * active Upstairs to terminate the connection.
1920
- *
1921
- * `new_work` and `add_work` both grab their work lock through this
1922
- * function. Let's say `promote_to_active` and `add_work` are racing for
1923
- * the work lock. If `add_work` wins the race it will put work into
1924
- * `active`, then `promote_to_active` will clear it out. If
1925
- * `promote_to_active` wins the race, it will change the Downstairs'
1926
- * active UpstairsConnection, and send the terminate signal to the
1927
- * tasks that are communicating to the previously active Upstairs
1928
- * (along with terminating the Downstairs tasks). If `add_work` for
1929
- * the previous Upstairs then does fire, it will fail to
1930
- * grab the lock because the UpstairsConnection is no longer active, and
1931
- * that `add_work` thread should close.
1932
- *
1933
- * Let's say `new_work` and `promote_to_active` are racing. If `new_work`
1934
- * wins, then it will return and run those jobs in `do_work_task`.
1935
- * However, `promote_to_active` will grab the lock and change the
1936
- * active UpstairsConnection, causing `do_work` to return
1937
- * UpstairsInactive for the jobs that were just returned. If
1938
- * `promote_to_active` wins, it will clear out the jobs of the old
1939
- * Upstairs.
1940
- *
1941
- * Grabbing the lock in this way should properly clear out the previously
1942
- * active Upstairs without causing jobs to be incorrectly sent to the
1943
- * newly active Upstairs.
1944
- */
1911
+ /// Mutably borrow a connection's `Work` if the `UpstairsConnection` matches
1912
+ ///
1913
+ /// Because this function takes a `&mut self` and returns a `&mut Work`
1914
+ /// (extending the lifetime of the initial borrow), it is impossible for
1915
+ /// anyone else to interfere with the work map for the lifetime of the
1916
+ /// borrow.
1945
1917
fn work_mut (
1946
1918
& mut self ,
1947
1919
upstairs_connection : UpstairsConnection ,
@@ -1954,6 +1926,7 @@ impl Downstairs {
1954
1926
Ok ( & mut active_upstairs. work )
1955
1927
}
1956
1928
1929
+ /// Borrow a connection's `Work` if the `UpstairsConnection` matches
1957
1930
fn work ( & self , upstairs_connection : UpstairsConnection ) -> Result < & Work > {
1958
1931
self . check_upstairs_active ( upstairs_connection) ?;
1959
1932
let active_upstairs = self
@@ -1971,7 +1944,7 @@ impl Downstairs {
1971
1944
if !self . active_upstairs . contains_key ( & upstairs_uuid) {
1972
1945
warn ! (
1973
1946
self . log,
1974
- "{:?} cannot grab work lock , {} is not active!" ,
1947
+ "{:?} cannot get active upstairs , {} is not active!" ,
1975
1948
upstairs_connection,
1976
1949
upstairs_uuid,
1977
1950
) ;
@@ -1984,7 +1957,7 @@ impl Downstairs {
1984
1957
if active_upstairs. upstairs_connection != upstairs_connection {
1985
1958
warn ! (
1986
1959
self . log,
1987
- "{:?} cannot grab lock , does not match {:?}!" ,
1960
+ "{:?} cannot get active upstairs , does not match {:?}!" ,
1988
1961
upstairs_connection,
1989
1962
active_upstairs. upstairs_connection,
1990
1963
) ;
@@ -2418,7 +2391,7 @@ impl Downstairs {
2418
2391
) -> Result < ( ) > {
2419
2392
let work = self . work_mut ( upstairs_connection) ?;
2420
2393
2421
- // If upstairs_connection grabs the work lock , it is the active
2394
+ // If upstairs_connection borrows the work map , it is the active
2422
2395
// connection for this Upstairs UUID. The job should exist in the Work
2423
2396
// struct. If it does not, then we're in the case where the same
2424
2397
// Upstairs has reconnected and been promoted to active, meaning
@@ -2495,8 +2468,8 @@ impl Downstairs {
2495
2468
if self . read_only {
2496
2469
// Multiple active read-only sessions are allowed, but multiple
2497
2470
// sessions for the same Upstairs UUID are not. Kick out a
2498
- // previously active session for this UUID if one exists. Do this
2499
- // while holding the work lock so the previously active Upstairs
2471
+ // previously active session for this UUID if one exists. This
2472
+ // function is called on a `&mut self`, so we're guaranteed that the
2500
2473
// isn't adding more work.
2501
2474
if let Some ( active_upstairs) = self
2502
2475
. active_upstairs
@@ -2882,9 +2855,9 @@ impl Work {
2882
2855
if let Some ( job) = self . active . get_mut ( & ds_id) {
2883
2856
if job. state == WorkState :: New || job. state == WorkState :: DepWait {
2884
2857
/*
2885
- * Before we can make this in_progress, we have to, while
2886
- * holding this locked, check the dep list if there is one
2887
- * and make sure all dependencies are completed.
2858
+ * Before we can make this in_progress, we have to check the dep
2859
+ * list if there is one and make sure all dependencies are
2860
+ * completed.
2888
2861
*/
2889
2862
let dep_list = job. work . deps ( ) ;
2890
2863
@@ -6029,7 +6002,7 @@ mod test {
6029
6002
assert_eq ! ( rx1. try_recv( ) . unwrap( ) , upstairs_connection_2) ;
6030
6003
6031
6004
// This should error with UpstairsInactive - upstairs_connection_1 isn't
6032
- // active anymore and can't grab the work lock .
6005
+ // active anymore and can't borrow the work map .
6033
6006
let result = ds. complete_work ( upstairs_connection_1, JobId ( 1000 ) , m) ;
6034
6007
assert ! ( matches!(
6035
6008
result. unwrap_err( ) . downcast:: <CrucibleError >( ) . unwrap( ) ,
@@ -6125,7 +6098,7 @@ mod test {
6125
6098
assert_eq ! ( rx1. try_recv( ) . unwrap( ) , upstairs_connection_2) ;
6126
6099
6127
6100
// This should error with UpstairsInactive - upstairs_connection_1 isn't
6128
- // active anymore and can't grab the work lock .
6101
+ // active anymore and can't borrow the work map .
6129
6102
let result = ds. complete_work ( upstairs_connection_1, JobId ( 1000 ) , m) ;
6130
6103
assert ! ( matches!(
6131
6104
result. unwrap_err( ) . downcast:: <CrucibleError >( ) . unwrap( ) ,
0 commit comments