[go: nahoru, domu]

Skip to content

Commit

Permalink
Remove non-working emscripten_fetch_wait / EMSCRIPTEN_FETCH_WAITABLE.…
Browse files Browse the repository at this point in the history
… NFC (#22138)

This API hasn't worked since the fastcomp days, so I think its probably
better to remove/deprecate it rather than try to make it work (perhaps
using pthreads).
  • Loading branch information
sbc100 committed Jun 24, 2024
1 parent b963a9b commit d079eca
Show file tree
Hide file tree
Showing 11 changed files with 9 additions and 205 deletions.
3 changes: 3 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ See docs/process.md for more on how version tagging works.

3.1.62 (in development)
-----------------------
- The `EMSCRIPTEN_FETCH_WAITABLE` flag along with the `emscripten_fetch_wait`
API were marked a deprecated. These feature have not functions for several
years now. (#22138)
- The internal `read_` function was removed. We now just use `readBinary` or
`readAsync`. (#22080)
- reference-types feature is now enabled by default in Emscripten, due to the
Expand Down
49 changes: 1 addition & 48 deletions site/source/docs/api_reference/fetch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -200,55 +200,8 @@ emscripten_fetch() returns.
- ``--proxy-to-worker`` + ``-pthread``: Synchronous Synchronous Fetch operations
are available both on the main thread and pthreads.

Waitable Fetches
================

Emscripten Fetch operations can also run in a third mode, called a *waitable*
fetch. Waitable fetches start off as asynchronous, but at any point after the
fetch has started, the calling thread can issue a wait operation to either wait
for the completion of the fetch, or to just poll whether the fetch operation has
yet completed. The following code sample illustrates how this works.

.. code-block:: cpp
int main() {
emscripten_fetch_attr_t attr;
emscripten_fetch_attr_init(&attr);
strcpy(attr.requestMethod, "GET");
attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_WAITABLE;
emscripten_fetch_t *fetch = emscripten_fetch(&attr, "file.dat"); // Starts as asynchronous.
EMSCRIPTEN_RESULT ret = EMSCRIPTEN_RESULT_TIMED_OUT;
while(ret == EMSCRIPTEN_RESULT_TIMED_OUT) {
/* possibly do some other work; */
ret = emscripten_fetch_wait(fetch, 0/*milliseconds to wait, 0 to just poll, INFINITY=wait until completion*/);
}
// The operation has finished, safe to examine the fields of the 'fetch' pointer now.
if (fetch->status == 200) {
printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
// The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
} else {
printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
}
emscripten_fetch_close(fetch);
}
Waitable fetches allow interleaving multiple tasks in one thread so that the
issuing thread can perform some other work until the fetch completes.

.. note::

Waitable fetches are available only in certain build modes:

- **No flags** or ``--proxy-to-worker``: Waitable fetches are not available.
- ``-pthread``: Waitable fetches are available on pthreads, but not
on the main thread.
- ``--proxy-to-worker`` + ``-pthread``: Waitable fetches are
available on all threads.

Tracking Progress
====================
=================

For robust fetch management, there are several fields available to track the
status of an XHR.
Expand Down
5 changes: 2 additions & 3 deletions src/generated_struct_info32.json
Original file line number Diff line number Diff line change
Expand Up @@ -1488,9 +1488,8 @@
"withCredentials": 60
},
"emscripten_fetch_t": {
"__attributes": 112,
"__proxyState": 108,
"__size__": 208,
"__attributes": 108,
"__size__": 200,
"data": 12,
"dataOffset": 24,
"id": 0,
Expand Down
1 change: 0 additions & 1 deletion src/generated_struct_info64.json
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,6 @@
},
"emscripten_fetch_t": {
"__attributes": 128,
"__proxyState": 124,
"__size__": 272,
"data": 24,
"dataOffset": 40,
Expand Down
1 change: 0 additions & 1 deletion src/struct_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,6 @@
"readyState",
"status",
"statusText",
"__proxyState",
"__attributes"
]
},
Expand Down
14 changes: 2 additions & 12 deletions system/include/emscripten/fetch.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ extern "C" {
// emscripten_fetch() while the operation is in progress.
#define EMSCRIPTEN_FETCH_SYNCHRONOUS 64

// If specified, it will be possible to call emscripten_fetch_wait() on the
// fetch to test or wait for its completion.
#define EMSCRIPTEN_FETCH_WAITABLE 128
#pragma clang deprecated(EMSCRIPTEN_FETCH_WAITABLE, "waitable fetch requests are no longer implemented")

struct emscripten_fetch_t;

Expand Down Expand Up @@ -190,8 +189,6 @@ typedef struct emscripten_fetch_t {
// Specifies a human-readable form of the status code.
char statusText[64];

_Atomic uint32_t __proxyState;

// For internal use only.
emscripten_fetch_attr_t __attributes;
} emscripten_fetch_t;
Expand All @@ -204,14 +201,7 @@ void emscripten_fetch_attr_init(emscripten_fetch_attr_t * _Nonnull fetch_attr);
// given URL or from IndexedDB database.
emscripten_fetch_t *emscripten_fetch(emscripten_fetch_attr_t * _Nonnull fetch_attr, const char * _Nonnull url);

// Synchronously blocks to wait for the given fetch operation to complete. This
// operation is not allowed in the main browser thread, in which case it will
// return EMSCRIPTEN_RESULT_NOT_SUPPORTED. Pass timeoutMSecs=infinite to wait
// indefinitely. If the wait times out, the return value will be
// EMSCRIPTEN_RESULT_TIMED_OUT.
// The onsuccess()/onerror()/onprogress() handlers will be called in the calling
// thread from within this function before this function returns.
EMSCRIPTEN_RESULT emscripten_fetch_wait(emscripten_fetch_t * _Nonnull fetch, double timeoutMSecs);
EMSCRIPTEN_RESULT emscripten_fetch_wait(emscripten_fetch_t * _Nonnull fetch, double timeoutMSecs) __attribute__((deprecated));

// Closes a finished or an executing fetch operation and frees up all memory. If
// the fetch operation was still executing, the onerror() handler will be called
Expand Down
55 changes: 1 addition & 54 deletions system/lib/fetch/emscripten_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,67 +147,14 @@ emscripten_fetch_t* emscripten_fetch(emscripten_fetch_attr_t* fetch_attr, const
}

EMSCRIPTEN_RESULT emscripten_fetch_wait(emscripten_fetch_t* fetch, double timeoutMsecs) {
#if __EMSCRIPTEN_PTHREADS__
if (!fetch) {
return EMSCRIPTEN_RESULT_INVALID_PARAM;
}
uint32_t proxyState = fetch->__proxyState;
if (proxyState == 2) {
// already finished.
return EMSCRIPTEN_RESULT_SUCCESS;
}
if (proxyState != 1) {
// the fetch should be ongoing?
return EMSCRIPTEN_RESULT_INVALID_PARAM;
}
#ifdef FETCH_DEBUG
emscripten_dbg("fetch: emscripten_fetch_wait..");
#endif
if (timeoutMsecs <= 0) {
return EMSCRIPTEN_RESULT_TIMED_OUT;
}
while (proxyState == 1 /*sent to proxy worker*/) {
if (emscripten_is_main_browser_thread()) {
emscripten_err("fetch: emscripten_fetch_wait failed: main thread cannot block to wait for long periods of time! Migrate the application to run in a worker to perform synchronous file IO, or switch to using asynchronous IO.");
return EMSCRIPTEN_RESULT_FAILED;
}
int ret = emscripten_futex_wait(&fetch->__proxyState, proxyState, timeoutMsecs);
if (ret == -ETIMEDOUT) {
return EMSCRIPTEN_RESULT_TIMED_OUT;
}
proxyState = fetch->__proxyState;
}
#ifdef FETCH_DEBUG
emscripten_dbg("fetch: emscripten_fetch_wait done..");
#endif

if (proxyState != 2) {
return EMSCRIPTEN_RESULT_FAILED;
}
return EMSCRIPTEN_RESULT_SUCCESS;
#else
if (fetch->readyState >= STATE_DONE) {
return EMSCRIPTEN_RESULT_SUCCESS; // already finished.
}
if (timeoutMsecs == 0) {
return EMSCRIPTEN_RESULT_TIMED_OUT /*Main thread testing completion with sleep=0msecs*/;
} else {
#ifdef FETCH_DEBUG
emscripten_err("fetch: emscripten_fetch_wait() cannot stop to wait when building without pthreads!");
#endif
return EMSCRIPTEN_RESULT_FAILED /*Main thread cannot block to wait*/;
}
#endif
return EMSCRIPTEN_RESULT_FAILED;
}

EMSCRIPTEN_RESULT emscripten_fetch_close(emscripten_fetch_t* fetch) {
if (!fetch) {
return EMSCRIPTEN_RESULT_SUCCESS; // Closing null pointer is ok, same as with free().
}

#if __EMSCRIPTEN_PTHREADS__
fetch->__proxyState = 0;
#endif
// This function frees the fetch pointer so that it is invalid to access it anymore.
// Use a few key fields as an integrity check that we are being passed a good pointer to a valid
// fetch structure, which has not been yet closed. (double close is an error)
Expand Down
36 changes: 0 additions & 36 deletions test/fetch/test_fetch_sync_in_main_thread.c

This file was deleted.

38 changes: 0 additions & 38 deletions test/fetch/test_fetch_waitable.c

This file was deleted.

11 changes: 0 additions & 11 deletions test/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4657,12 +4657,6 @@ def test_fetch_sync_xhr_in_proxy_to_worker(self):
self.btest_exit('fetch/test_fetch_sync_xhr.cpp',
args=['-sFETCH_DEBUG', '-sFETCH', '--proxy-to-worker'])

# Tests waiting on EMSCRIPTEN_FETCH_WAITABLE request from a worker thread
@unittest.skip("emscripten_fetch_wait relies on an asm.js-based web worker")
def test_fetch_sync_fetch_in_main_thread(self):
shutil.copyfile(test_file('gears.png'), 'gears.png')
self.btest_exit('fetch/test_fetch_sync_in_main_thread.cpp', args=['-sFETCH_DEBUG', '-sFETCH', '-sWASM=0', '-pthread', '-sPROXY_TO_PTHREAD'])

@disabled('https://github.com/emscripten-core/emscripten/issues/16746')
def test_fetch_idb_store(self):
self.btest_exit('fetch/test_fetch_idb_store.cpp', args=['-pthread', '-sFETCH', '-sPROXY_TO_PTHREAD'])
Expand Down Expand Up @@ -4692,11 +4686,6 @@ def test_fetch_stream_async(self):
create_file('myfile.dat', 'hello world\n' * 1000)
self.btest_exit('fetch/test_fetch_stream_async.c', args=['-sFETCH'])

@disabled('waitable fetch operations were disabled when the fetch worker was removed')
def test_fetch_waitable(self):
create_file('myfile.dat', 'hello world\n' * 1000)
self.btest_exit('fetch/test_fetch_waitable.c', args=['-sFETCH'])

def test_fetch_persist(self):
create_file('myfile.dat', 'hello world\n')
self.btest_exit('fetch/test_fetch_persist.c', args=['-sFETCH'])
Expand Down
1 change: 0 additions & 1 deletion test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -13568,7 +13568,6 @@ def test_build_fetch_tests(self):
self.build(test_file('fetch/test_fetch_idb_store.c'))
self.build(test_file('fetch/test_fetch_stream_async.c'))
self.build(test_file('fetch/test_fetch_sync.c'))
self.build(test_file('fetch/test_fetch_waitable.c'))
self.build(test_file('fetch/test_fetch_progress.c'))

def test_fetch_init_node(self):
Expand Down

0 comments on commit d079eca

Please sign in to comment.