Skip to content

Commit 397b507

Browse files
authored
Merge pull request emscripten-core#13 from rstz/flexible-pthreadfs-folder
Rename special folder to `persistent/` and add support for changing the folder name
2 parents 8d9ab82 + 8d41d04 commit 397b507

21 files changed

+148
-110
lines changed

pthreadfs/README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Alternatively, you may enable the API with Chrome's " --enable-runtime-features=
1717
```
1818
open -a /Applications/Google\ Chrome\ Canary.app --args --enable-runtime-features=FileSystemAccessAccessHandle
1919
```
20+
21+
Both Storage Foundation API and OPFS are available as [origin trials](https://developer.chrome.com/origintrials/) in Chrome 95.
2022
## Getting the code
2123

2224
PthreadFS is available on Github in the [emscripten-pthreadfs](https://github.com/rstz/emscripten-pthreadfs) repository. All code resides in the `pthreadfs` folder. It should be usable with any up-to-date Emscripten version.
@@ -29,15 +31,17 @@ In order to use the code in a new project, you only need the three files in the
2931

3032
### Code changes
3133

32-
- PThreadFS maintains a virtual file system. The OPFS backend is mounted at `/pthreadfs/`. Only files in this folder are persisted between sessions. All other files will be stored in-memory through MEMFS.
34+
- PThreadFS maintains a virtual file system. The OPFS backend is mounted at `/persistent/`. Only files in this folder are persisted between sessions. All other files will be stored in-memory through MEMFS.
35+
36+
You may specify the folder used by PThreadFS by modifying the `PTHREADFS_FOLDER` preprocessor definition, e.g. by compiling with `-DPTHREADFS_FOLDER=mypthreadfsfolder`.
3337

3438
### Build process changes
3539

3640
There are two changes required to build a project with PThreadFS:
3741
- Compile `pthreadfs.h` and `pthreadfs.cpp` and link the resulting object to your application. Add `-pthread` to the compiler flag to include support for pthreads.
3842
- Add the following options to the linking step:
3943
```
40-
-pthread -O2 -s PROXY_TO_PTHREAD --js-library=library_pthreadsfs.js
44+
-pthread -O2 -s PROXY_TO_PTHREAD --js-library=library_pthreadfs.js
4145
```
4246
**Example**
4347
If your build process was
@@ -46,7 +50,7 @@ emcc myproject.cpp -o myproject.html
4650
```
4751
Your new build step should be
4852
```shell
49-
emcc -pthread -s PROXY_TO_PTHREAD -O3 --js-library=library_pthreadfs.js myproject.cpp pthreadfs.cpp -o myproject.html
53+
emcc -pthread -s PROXY_TO_PTHREAD -O2 --js-library=library_pthreadfs.js myproject.cpp pthreadfs.cpp -o myproject.html
5054
```
5155

5256
### Advanced Usage
@@ -62,11 +66,11 @@ See `pthreadfs/examples/emscripten-tests/fsafs.cpp` for exemplary usage.
6266

6367
## Known Limitations
6468

65-
- All files to be stored using the file system access Access Handles must be stored in the `/pthreadfs` folder.
66-
- Files in the `/pthreadfs` folder cannot interact through syscalls with other files (e.g. moving, copying, etc.).
69+
- All files to be stored using the file system access Access Handles must be stored in the `/persistent` folder.
70+
- Files in the `/persistent` folder cannot interact through syscalls with other files (e.g. moving, copying, etc.).
6771
- The code is still prototype quality and **should not be used in a production environment** yet. It is possible that the use of PThreadFS might lead to subtle bugs in other libraries.
6872
- PThreadFS requires PROXY_TO_PTHREAD to be active. In particular, no system calls interacting with the file system should be called from the main thread.
69-
- Some functionality of the Emscripten File System API is missing, such as sockets, file packager, IndexedDB integration and support for XHRequests.
73+
- Some functionality of the Emscripten File System API is missing, such as sockets, IndexedDB integration and support for XHRequests.
7074
- PThreadFS depends on C++ libraries. `EM_PTHREADFS_ASM()` cannot be used within C files.
7175
- Performance is good if and only if optimizations (compiler option `-O2`) are enabled and DevTools are closed.
7276
- Accessing the file system before `main()` is called may not work.

pthreadfs/examples/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ CFLAGS = \
6969
-$(OPTIMIZATION_LEVEL) \
7070
-Wall \
7171
-pthread \
72-
-I..
72+
-I..
7373

7474
CFLAGS_SQLITE = \
7575
$(CFLAGS) \
@@ -144,12 +144,12 @@ preload-tests: dist/$(PRELOADTESTS)/no_pthreadfs.html dist/$(PRELOADTESTS)/prelo
144144

145145
dist/$(PRELOADTESTS)/preload_filepackage.js: $(PRELOADFILES) $(FILE_PACKAGER)
146146
mkdir -p dist/preload-tests/
147-
python3 $(FILE_PACKAGER) $(addsuffix .data, $(basename $@)) --preload ./$(PRELOADTESTS)/input@/pthreadfs --use_pthreadfs --js-output=$@
147+
python3 $(FILE_PACKAGER) $(addsuffix .data, $(basename $@)) --preload ./$(PRELOADTESTS)/input@/persistent --use_pthreadfs --js-output=$@
148148

149149
dist/$(PRELOADTESTS)/preload_pthreadfs.html: $(OBJ)/preload.o $(OBJ)/pthreadfs.o dist/$(PRELOADTESTS)/preload_filepackage.js $(PTHREADFS_JS)
150150
mkdir -p dist/preload-tests
151151
$(EMCC) $(LINK_FLAGS) -o $@ --js-library=$(PTHREADFS_JS) --pre-js $(word 3,$^) $< $(word 2,$^)
152152

153153
dist/$(PRELOADTESTS)/no_pthreadfs.html: $(OBJ)/preload.o $(PRELOADFILES)
154154
mkdir -p dist/preload-tests
155-
$(EMCC) $(LINK_FLAGS) -o $@ --preload-file $(PRELOADTESTS)/input@/pthreadfs $<
155+
$(EMCC) $(LINK_FLAGS) -o $@ --preload-file $(PRELOADTESTS)/input@/persistent $<

pthreadfs/examples/emscripten-tests/FAIL_early_stat64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class EarlyObject {
2323
puts("Start constructing EarlyObject.");
2424
int err;
2525
struct stat s;
26-
err = stat("pthreadfs/", &s);
26+
err = stat("persistent/", &s);
2727
assert(!err);
2828
}
2929
};

pthreadfs/examples/emscripten-tests/FAIL_links.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ int main() {
1414
puts("WARNING: This test will fail. Update this message if the test succeeds.");
1515

1616
EM_PTHREADFS_ASM(
17-
await PThreadFS.mkdir('pthreadfs/working');
18-
await PThreadFS.mkdir('pthreadfs/test');
19-
await PThreadFS.chdir('pthreadfs/working');
17+
await PThreadFS.mkdir('persistent/working');
18+
await PThreadFS.mkdir('persistent/test');
19+
await PThreadFS.chdir('persistent/working');
2020
await PThreadFS.symlink('../test/../there!', 'link');
2121
await PThreadFS.writeFile('file', 'test');
2222
await PThreadFS.mkdir('folder');

pthreadfs/examples/emscripten-tests/FAIL_realpath.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ void setup() {
2222
int err;
2323
err = mkdir("emptyfolder", 0777);
2424
assert(!err);
25-
err = mkdir("pthreadfs/emptypthreadfsfolder", 0777);
25+
err = mkdir("persistent/emptypthreadfsfolder", 0777);
2626
assert(!err);
2727
create_file("file.txt", "Some non-pthreadfs file content", 0666);
28-
create_file("pthreadfs/pthreadfile.txt", "ride into the super dangerous pthreadFS zone", 0666);
28+
create_file("persistent/pthreadfile.txt", "ride into the super dangerous pthreadFS zone", 0666);
2929
}
3030

3131
void cleanup() {
3232
rmdir("emptyfolder");
3333
unlink("file.txt");
34-
unlink("pthreadfs/file.txt");
34+
unlink("persistent/file.txt");
3535
}
3636

3737
void test() {
@@ -47,18 +47,18 @@ void test() {
4747
assert(res);
4848
printf("emptyfolder/../file.txt is at %s.\n", buf);
4949

50-
res = realpath("pthreadfs/pthreadfile.txt", buf);
50+
res = realpath("persistent/pthreadfile.txt", buf);
5151
assert(res);
52-
printf("pthreadfs/pthreadfile.txt is at %s.\n", buf);
53-
res = realpath("pthreadfs/doesnotexist.txt", buf);
52+
printf("persistent/pthreadfile.txt is at %s.\n", buf);
53+
res = realpath("persistent/doesnotexist.txt", buf);
5454
assert(!res);
55-
printf("pthreadfs/doesnotexist.txt does not exist.\n");
56-
res = realpath("emptyfolder/../pthreadfs/pthreadfsfile.txt", buf);
55+
printf("persistent/doesnotexist.txt does not exist.\n");
56+
res = realpath("emptyfolder/../persistent/pthreadfsfile.txt", buf);
5757
assert(res);
58-
printf("emptyfolder/../pthreadfs/pthreadfsfile.txt is at %s.\n", buf);
59-
res = realpath("pthreadfs/emptypthreadfsfolder/../file.txt", buf);
58+
printf("emptyfolder/../persistent/pthreadfsfile.txt is at %s.\n", buf);
59+
res = realpath("persistent/emptypthreadfsfolder/../file.txt", buf);
6060
assert(res);
61-
printf("pthreadfs/emptypthreadfsfolder/../file.txt is at %s.\n", buf);
61+
printf("persistent/emptypthreadfsfolder/../file.txt is at %s.\n", buf);
6262

6363
puts("success");
6464
}

pthreadfs/examples/emscripten-tests/fsafs.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
int main () {
99
std::cout << "Proof that stdout works fine.\n";
1010
std::ofstream myfile;
11-
myfile.open ("pthreadfs/example");
11+
myfile.open ("persistent/example");
1212
myfile << "Writing a few characters.\n";
1313
myfile.close();
1414

1515
std::string line;
16-
std::ifstream myfile_read ("pthreadfs/example");
16+
std::ifstream myfile_read ("persistent/example");
1717

1818
if (myfile_read.is_open()) {
1919
std::getline(myfile_read, line);
@@ -22,15 +22,15 @@ int main () {
2222
myfile_read.close();
2323
}
2424

25-
std::ofstream stream1 ("pthreadfs/multistreamexample");
26-
std::ofstream stream2 ("pthreadfs/multistreamexample");
25+
std::ofstream stream1 ("persistent/multistreamexample");
26+
std::ofstream stream2 ("persistent/multistreamexample");
2727
stream1 << "Write a line through stream1.\n";
2828
stream2 << "Write a line through stream2.\n";
2929
stream1.close();
3030
stream2.close();
3131

32-
std::remove("pthreadfs/multistreamexample");
33-
bool can_open_deleted_file = (bool) std::ifstream("pthreadfs/multistreamexample");
32+
std::remove("persistent/multistreamexample");
33+
bool can_open_deleted_file = (bool) std::ifstream("persistent/multistreamexample");
3434
if(!can_open_deleted_file) {
3535
std::cout << "Opening deleted file failed, as expected.\n";
3636
}

pthreadfs/examples/emscripten-tests/multiple_threads.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
#include <vector>
66
#include <thread>
77
#include <emscripten.h>
8-
#include "pthreadfs.h"
8+
99

1010

1111
void threadMain(int msg) {
1212
size_t thread_id = std::hash<std::thread::id>{}(std::this_thread::get_id());
1313
std::ofstream myfile;
14-
myfile.open ("pthreadfs/multi_threading_example", std::ios_base::app);
14+
myfile.open ("persistent/multi_threading_example", std::ios_base::app);
1515
myfile << "Writing from thread " << msg << " Id: " << thread_id << " ";
1616
myfile.close();
1717
EM_ASM({console.log(`Wrote on thread ${$0}`);}, thread_id);
@@ -20,7 +20,7 @@ void threadMain(int msg) {
2020

2121
int main () {
2222
EM_ASM({console.log("Hello from main");});
23-
std::remove("pthreadfs/multi_threading_example");
23+
std::remove("persistent/multi_threading_example");
2424

2525
constexpr int number_of_threads = 10;
2626

@@ -34,7 +34,7 @@ int main () {
3434
}
3535

3636
std::ofstream myfile;
37-
myfile.open ("pthreadfs/multi_threading_example");
37+
myfile.open ("persistent/multi_threading_example");
3838
myfile << "Writing the main thread.\n";
3939
myfile.close();
4040

pthreadfs/examples/emscripten-tests/open_options.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ void create_file(const char *path, const char *buffer, int mode) {
3333
void setup() {
3434
// struct utimbuf t = {1200000000, 1200000000};
3535

36-
mkdir("pthreadfs/folder", 0777);
37-
create_file("pthreadfs/folder/file", "abcdef", 0777);
36+
mkdir("persistent/folder", 0777);
37+
create_file("persistent/folder/file", "abcdef", 0777);
3838
//symlink("file", "folder/file-link");
3939

4040
//utime("folder/file", &t);
@@ -44,13 +44,13 @@ void setup() {
4444
}
4545

4646
void cleanup() {
47-
unlink("pthreadfs/folder/file");
47+
unlink("persistent/folder/file");
4848
// unlink("folder/file-link");
49-
rmdir("pthreadfs/folder");
49+
rmdir("persistent/folder");
5050
}
5151

5252
void test() {
53-
create_file("pthreadfs/folder/file", "blubbbbb", 0777);
53+
create_file("persistent/folder/file", "blubbbbb", 0777);
5454
}
5555

5656
int main() {

pthreadfs/examples/emscripten-tests/readdir.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,17 @@ void setup() {
3232
assert(!err);
3333
err = mkdir("foobar", 0777);
3434
assert(!err);
35-
err = mkdir("pthreadfs/readdir_test", 0777);
35+
err = mkdir("persistent/readdir_test", 0777);
3636
create_file("foobar/file.txt", "ride into the danger zone", 0666);
37-
create_file("pthreadfs/readdir_test/file.txt", "ride into the super dangerous pthreadFS zone", 0666);
37+
create_file("persistent/readdir_test/file.txt", "ride into the super dangerous pthreadFS zone", 0666);
3838
}
3939

4040
void cleanup() {
4141
rmdir("nocanread");
4242
unlink("foobar/file.txt");
4343
rmdir("foobar");
44-
unlink("pthreadfs/readdir_test/file.txt");
45-
rmdir("pthreadfs/readdir_test");
44+
unlink("persistent/readdir_test/file.txt");
45+
rmdir("persistent/readdir_test");
4646
}
4747

4848
void test(const char* foldername) {
@@ -193,7 +193,7 @@ int main() {
193193
setup();
194194
test("foobar");
195195
test_scandir();
196-
test("pthreadfs/readdir_test");
196+
test("persistent/readdir_test");
197197
cleanup();
198198
return EXIT_SUCCESS;
199199
}

pthreadfs/examples/emscripten-tests/remove.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@ void create_file(const char *path, const char *buffer, int mode) {
3131
}
3232

3333
void setup() {
34-
mkdir("pthreadfs/folder", 0777);
35-
create_file("pthreadfs/folder/file", "abcdef", 0777);
34+
mkdir("persistent/folder", 0777);
35+
create_file("persistent/folder/file", "abcdef", 0777);
3636
}
3737

3838
void cleanup() {
39-
unlink("pthreadfs/folder/file");
40-
rmdir("pthreadfs/folder");
39+
unlink("persistent/folder/file");
40+
rmdir("persistent/folder");
4141
}
4242

4343
void test() {
44-
remove("pthreadfs/folder/file");
45-
remove("pthreadfs/folder");
44+
remove("persistent/folder/file");
45+
remove("persistent/folder");
4646
puts("success");
4747
}
4848

pthreadfs/examples/emscripten-tests/rename.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include <fstream>
33
#include <cstdio>
44
#include <emscripten.h>
5-
#include "pthreadfs.h"
5+
66

77
int main()
88
{
@@ -48,36 +48,36 @@ int main()
4848

4949
// PThreadFS file that is closed when renaming.
5050
std::ofstream closed_pthreadfs_file;
51-
closed_pthreadfs_file.open ("pthreadfs/old_closed_pthreadfs_file");
51+
closed_pthreadfs_file.open ("persistent/old_closed_pthreadfs_file");
5252
closed_pthreadfs_file << "Contents of closed_pthreadfs_file.";
5353
closed_pthreadfs_file.close();
5454

55-
if (std::rename("pthreadfs/old_closed_pthreadfs_file", "pthreadfs/new_closed_pthreadfs_file")) {
55+
if (std::rename("persistent/old_closed_pthreadfs_file", "persistent/new_closed_pthreadfs_file")) {
5656
std::cout << "Error renaming closed_pthreadfs_file\n";
5757
return 1;
5858
}
5959
std::cout << "Rename closed_pthreadfs_file successfully\n";
6060
closed_pthreadfs_file.close();
6161

62-
if(std::remove("pthreadfs/new_closed_pthreadfs_file")) {
62+
if(std::remove("persistent/new_closed_pthreadfs_file")) {
6363
std::cout << "Removing closed_pthreadfs_file failed\n";
6464
return 1;
6565
}
6666
std::cout << "Removed closed_pthreadfs_file\n";
6767

6868
// PThreadFS file that is open when renaming.
6969
std::ofstream open_pthreadfs_file;
70-
open_pthreadfs_file.open ("pthreadfs/old_open_pthreadfs_file");
70+
open_pthreadfs_file.open ("persistent/old_open_pthreadfs_file");
7171
open_pthreadfs_file << "Contents of open_pthreadfs_file.";
7272

73-
if (std::rename("pthreadfs/old_open_pthreadfs_file", "pthreadfs/new_open_pthreadfs_file")) {
73+
if (std::rename("persistent/old_open_pthreadfs_file", "persistent/new_open_pthreadfs_file")) {
7474
std::cout << "Error renaming open_pthreadfs_file\n";
7575
return 1;
7676
}
7777
std::cout << "Rename open_pthreadfs_file successfully\n";
7878
open_pthreadfs_file.close();
7979

80-
if(std::remove("pthreadfs/new_open_pthreadfs_file")) {
80+
if(std::remove("persistent/new_open_pthreadfs_file")) {
8181
std::cout << "Removing open_pthreadfs_file failed.\n";
8282
std::cout << "This is expected when using the OPFS backend.\n";
8383
return 1;

0 commit comments

Comments
 (0)