Skip to content

Commit

Permalink
Merge branch 'dev-0.8'
Browse files Browse the repository at this point in the history
  • Loading branch information
birdofpreyru committed Jul 21, 2023
2 parents 9758fe6 + e97c275 commit 7a58473
Show file tree
Hide file tree
Showing 14 changed files with 2,106 additions and 2,481 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Android|Windows")
endif()

execute_process(
COMMAND cmake ${CMAKE_CURRENT_SOURCE_DIR}/pcre2
COMMAND ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/pcre2
-B ${CMAKE_BINARY_DIR}/pcre2
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/sysroot
Expand All @@ -78,7 +78,7 @@ execute_process(
)

execute_process(
COMMAND cmake --build ${CMAKE_BINARY_DIR}/pcre2
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/pcre2
--config Release
${PCRE2_TARGET}
)
Expand All @@ -92,7 +92,7 @@ if(
# as of now.
AND NOT CMAKE_SYSTEM_NAME MATCHES "Darwin"
)
execute_process(COMMAND cmake --install ${CMAKE_BINARY_DIR}/pcre2)
execute_process(COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR}/pcre2)
endif()

# Copies shared PCRE2 library into the folder from where Gradle automatically
Expand Down
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ Embed HTTP server for [React Native] applications for Android, iOS, Mac (Catalys
and Windows platforms. Powered by [Lighttpd] server, supports both [new][New Architecture]
and [old][Old Architecture] RN architectures.

**BEWARE:** _The Windows support is broken in the version v0.8.0, rely on
the library version v0.7.13 instead, for now._

[![Sponsor](https://raw.githubusercontent.com/birdofpreyru/react-native-static-server/master/.README/sponsor.svg)](https://github.com/sponsors/birdofpreyru)

### Sponsored By:
Expand Down Expand Up @@ -64,6 +61,11 @@ the library version v0.7.13 instead, for now._
[the example project][example app] included into the library repository._

- [CMake] is required on the build host.

- When building for **Android**, [CMake] should be installed as a part of your
_Android SDK_ (open _SDK Manager_, and look for [CMake] within
the _SDK Tools_ tab).

- On **MacOS**, the `pkg-config` dependency is also needed. You can install both via [Homebrew],
by executing:
```shell
Expand All @@ -82,11 +84,6 @@ the library version v0.7.13 instead, for now._
For details read: https://earthly.dev/blog/homebrew-on-m1,
and [Issue#29](https://github.com/birdofpreyru/react-native-static-server/issues/29).
- On **Ubuntu** you may get it by executing
```shell
$ sudo apt-get update && sudo apt-get install cmake
```
- Install the package:
```shell
$ npm install --save @dr.pogodin/react-native-static-server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.util.concurrent.Semaphore;
import java.util.Enumeration;
import java.util.function.BiConsumer;

Expand All @@ -27,6 +28,15 @@
public class ReactNativeStaticServerModule
extends ReactNativeStaticServerSpec implements LifecycleEventListener
{
// This semaphore is used to atomize server start-up and shut-down operations.
// It is acquired in the very beginning of start() and stop() methods; and it
// is normally released on the first subsequent signal from the server, at
// the same moment the pendingPromise for those start() and stop() is resolved.
// In edge cases, when start() or stop() is aborted due to failed runtime
// invariant checks, this semaphore is released at those abort points, which
// are in all cases prior to assigning the pendingPromise value.
private static Semaphore sem = new Semaphore(1, true);

// The currently active server instance. We assume only single server instance
// can be active at any time, thus a simple field should be enought for now.
// If we arrive to having possibility of multiple servers running in
Expand Down Expand Up @@ -94,13 +104,23 @@ public void start(
) {
Log.i(LOGTAG, "Starting...");

try {
sem.acquire();
} catch (Exception e) {
Errors.INTERNAL_ERROR.log(e)
.reject(promise, "Failed to acquire a semaphore");
return;
}

if (server != null) {
Errors.ANOTHER_INSTANCE_IS_ACTIVE.log().reject(promise);
sem.release();
return;
}

if (pendingPromise != null) {
Errors.INTERNAL_ERROR.log().reject(promise, "Unexpected pending promise");
sem.release();
return;
}

Expand All @@ -123,11 +143,11 @@ public void accept(String signal, String details) {
event.putString("details", details);
emitter.emit("RNStaticServer", event);
} else {
Promise p = pendingPromise;
pendingPromise = null;
if (signal == Server.CRASHED) {
Errors.SERVER_CRASHED.reject(p, details);
} else p.resolve(details);
Errors.SERVER_CRASHED.reject(pendingPromise, details);
} else pendingPromise.resolve(details);
pendingPromise = null;
sem.release();
}
}
}
Expand All @@ -150,20 +170,25 @@ public void getOpenPort(String address, Promise promise) {

@ReactMethod
public void stop(Promise promise) {
try {
Log.i(LOGTAG, "stop() triggered.");
Log.i(LOGTAG, "stop() triggered");

if (pendingPromise != null) {
Errors.INTERNAL_ERROR
.reject(pendingPromise, "Unexpected pending promise");
return;
}

pendingPromise = promise;
server.interrupt();
try {
sem.acquire();
} catch (Exception e) {
Errors.STOP_FAILURE.log(e).reject(promise);
Errors.INTERNAL_ERROR.log(e)
.reject(promise, "Failed to acquire a semaphore");
return;
}

if (pendingPromise != null) {
Errors.INTERNAL_ERROR
.reject(pendingPromise, "Unexpected pending promise");
sem.release();
return;
}

pendingPromise = promise;
server.interrupt();
}

@ReactMethod
Expand Down
8 changes: 6 additions & 2 deletions android/src/main/java/com/lighttpd/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,17 @@ public void run() {
if (res != 0) {
throw new Exception("Native server exited with status " + res);
}

// NOTE: It MUST BE set "null" prior to sending out TERMINATED or CRASHED
// signals.
activeServer = null;

Log.i(LOGTAG, "Server terminated gracefully");
signalConsumer.accept(TERMINATED, null);
} catch (Exception error) {
activeServer = null;
Log.e(LOGTAG, "Server crashed", error);
signalConsumer.accept(CRASHED, error.getMessage());
} finally {
activeServer = null;
}
}
}
Loading

0 comments on commit 7a58473

Please sign in to comment.