Fix nu_select! macro for borrowck
This commit is contained in:
parent
322c937c3c
commit
6f7e73d6b4
|
@ -341,7 +341,7 @@ impl<'tree> Iterator<&'tree Block> for RevStaleBlockIter<'tree> {
|
||||||
/// This function emulates the GetCompact(SetCompact(n)) in the satoshi code,
|
/// This function emulates the GetCompact(SetCompact(n)) in the satoshi code,
|
||||||
/// which drops the precision to something that can be encoded precisely in
|
/// which drops the precision to something that can be encoded precisely in
|
||||||
/// the nBits block header field. Savour the perversity. This is in Bitcoin
|
/// the nBits block header field. Savour the perversity. This is in Bitcoin
|
||||||
/// consensus code. What. The. Fuck.
|
/// consensus code. What. Gaah!
|
||||||
fn satoshi_the_precision(n: &Uint256) -> Uint256 {
|
fn satoshi_the_precision(n: &Uint256) -> Uint256 {
|
||||||
// Shift by B bits right then left to turn the low bits to zero
|
// Shift by B bits right then left to turn the low bits to zero
|
||||||
let bits = 8 * ((n.bits() + 7) / 8 - 3);
|
let bits = 8 * ((n.bits() + 7) / 8 - 3);
|
||||||
|
|
|
@ -28,15 +28,6 @@ macro_rules! nu_select(
|
||||||
use rustrt::task::Task;
|
use rustrt::task::Task;
|
||||||
use sync::comm::Packet;
|
use sync::comm::Packet;
|
||||||
|
|
||||||
/// Obtains a borrowed reference to an object for an arbitrary amount of
|
|
||||||
/// time (it is on you to make sure the aliasing rules are followed and
|
|
||||||
/// that the borrow does not exceed the object's lifetime!!!!!!!!!!!!!!)
|
|
||||||
/// to subvert the borrow-checker. This is a workaround for the current
|
|
||||||
/// lexical-scope-based borrow times.
|
|
||||||
unsafe fn borrow_without_checking<'a, 'b, T>(obj: &'a T) -> &'b T {
|
|
||||||
&*(obj as *const _)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is anything already ready to receive? Grab it without waiting.
|
// Is anything already ready to receive? Grab it without waiting.
|
||||||
$(
|
$(
|
||||||
if (&$rx as &Packet).can_recv() {
|
if (&$rx as &Packet).can_recv() {
|
||||||
|
@ -51,7 +42,8 @@ macro_rules! nu_select(
|
||||||
// that we started.
|
// that we started.
|
||||||
let mut started_count = 0;
|
let mut started_count = 0;
|
||||||
// Restrict lifetime of borrows in `packets`
|
// Restrict lifetime of borrows in `packets`
|
||||||
let packets = [ $( unsafe { borrow_without_checking(&$rx) } as &Packet, )+ ];
|
{
|
||||||
|
let packets = [ $( &$rx as &Packet, )+ ];
|
||||||
|
|
||||||
let task: Box<Task> = Local::take();
|
let task: Box<Task> = Local::take();
|
||||||
task.deschedule(packets.len(), |task| {
|
task.deschedule(packets.len(), |task| {
|
||||||
|
@ -63,29 +55,31 @@ macro_rules! nu_select(
|
||||||
Err(task) => Err(task)
|
Err(task) => Err(task)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let mut i = -1;
|
let mut i = 0;
|
||||||
$(
|
let ret = $(
|
||||||
// Abort every one, but only react to the first
|
// Abort the receivers, stopping at the first ready one to get its data.
|
||||||
if { i += 1; i < started_count } &&
|
if { i += 1; i <= started_count } &&
|
||||||
// If start_selection() failed, abort_selection() will fail too,
|
// If start_selection() failed, abort_selection() will fail too,
|
||||||
// but it still counts as "data available".
|
// but it still counts as "data available".
|
||||||
(packets[i].abort_selection() || i == started_count - 1) {
|
($rx.abort_selection() || i == started_count) {
|
||||||
// Abort the remainder, ignoring their return values
|
|
||||||
i += 1;
|
|
||||||
while i < started_count {
|
|
||||||
packets[i].abort_selection();
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
// End manually-tracked borrow of $rx in packets
|
|
||||||
drop(packets);
|
|
||||||
// React to the first
|
// React to the first
|
||||||
let $name = $rx.$meth();
|
let $name = $rx.$meth();
|
||||||
$code
|
$code
|
||||||
}
|
})else+
|
||||||
)else+
|
|
||||||
else {
|
else {
|
||||||
fail!("we didn't find the ready receiver, but we should have had one"); }
|
fail!("we didn't find the ready receiver, but we should have had one");
|
||||||
|
};
|
||||||
|
// At this point, the first i receivers have been aborted. We need to abort the rest:
|
||||||
|
$(if i > 0 {
|
||||||
|
i -= 1;
|
||||||
|
} else {
|
||||||
|
$rx.abort_selection();
|
||||||
|
})+
|
||||||
|
let _ = i; // Shut up `i -= 1 but i is never read` warning
|
||||||
|
// Return
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue