forked from elast0ny/shared_memory
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathposix_semantics.rs
More file actions
90 lines (87 loc) · 3.54 KB
/
posix_semantics.rs
File metadata and controls
90 lines (87 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use shared_memory_extended::ShmemConf;
use std::sync::mpsc::channel;
use std::thread;
#[test]
fn persistence() {
let os_id = {
let mut shmem = ShmemConf::new().size(4096).create().unwrap();
shmem.set_owner(false);
String::from(shmem.get_os_id())
};
let mut shmem = ShmemConf::new().os_id(os_id).open().unwrap();
shmem.set_owner(true);
}
#[test]
fn posix_behavior() {
let (tx_a, rx_a) = channel();
let (tx_b, rx_b) = channel();
let (tx_c, rx_c) = channel();
let thread_a = thread::Builder::new()
.name(String::from("A"))
.spawn(move || {
let os_id = {
let shmem = ShmemConf::new().size(4096).create().unwrap();
let os_id = String::from(shmem.get_os_id());
// Creating two `Shmem`s with the same `os_id` should fail
assert!(ShmemConf::new().size(4096).os_id(&os_id).create().is_err());
tx_b.send(os_id.clone()).unwrap();
tx_c.send(os_id.clone()).unwrap();
// Wait for threads B and C to confirm they have created their instances.
rx_a.recv().unwrap();
rx_a.recv().unwrap();
// Tell thread B to drop its instance.
tx_b.send(String::new()).unwrap();
os_id
// Owned shmem drops here after a second owned instance has been
// dropped in thread B.
};
// Should not be able to reopen shared memory after an owned instance
// has been dropped in thread B.
assert!(ShmemConf::new().size(4096).os_id(os_id).open().is_err());
// Tell thread C to drop the unowned instance.
tx_c.send(String::new()).unwrap();
})
.unwrap();
let thread_b = thread::Builder::new()
.name(String::from("B"))
.spawn({
let tx_a = tx_a.clone();
move || {
let existing_os_id = rx_b.recv().unwrap();
// Creating two `Shmem`s with the same `os_id` should fail
assert!(ShmemConf::new()
.size(4096)
.os_id(&existing_os_id)
.create()
.is_err());
{
// Should be able to open the existing shared memory
let mut shmem = ShmemConf::new().os_id(&existing_os_id).open().unwrap();
shmem.set_owner(true);
tx_a.send(String::new()).unwrap();
rx_b.recv().unwrap();
// When the owning shmem is dropped here, we
// 1. should be able to still drop the original shared memory in thread A.
// 2. should not be able to reopen it with the same name in thread A, even
// if an instance is kept alive in thread C.
}
}
})
.unwrap();
let thread_c = thread::Builder::new()
.name(String::from("C"))
.spawn(move || {
// This thread keeps a shared memory instance alive until it's told to
// drop it.
let existing_os_id = rx_c.recv().unwrap();
let _shmem = ShmemConf::new().os_id(existing_os_id).open().unwrap();
// Indicate to thread A that the instance has been created.
tx_a.send(String::new()).unwrap();
// Shut down signal.
rx_c.recv().unwrap();
})
.unwrap();
thread_a.join().unwrap();
thread_b.join().unwrap();
thread_c.join().unwrap();
}