@wasm-oj/server 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,7 @@ use crate::{
6
6
  },
7
7
  types::DeterminismConfig,
8
8
  };
9
+ use std::cell::Cell;
9
10
  use std::sync::{Arc, Mutex};
10
11
  use wasmer::{
11
12
  AsStoreMut, Extern, Function, FunctionEnv, FunctionEnvMut, Imports, Memory, Memory32, Memory64,
@@ -239,6 +240,23 @@ struct PollEnv {
239
240
  clock: VirtualClock,
240
241
  }
241
242
 
243
+ thread_local! {
244
+ static STDIN_READINESS_DEFERRALS: Cell<u64> = const { Cell::new(0) };
245
+ }
246
+
247
+ /// Whether an empty stdin readiness check may return `Pending` instead of
248
+ /// blocking. A clock probe never blocks. A poll without a clock grants one
249
+ /// deferral per read subscription, so WASIX reports any other ready
250
+ /// subscription first and blocks on stdin only when it would wait anyway.
251
+ #[cfg(target_arch = "wasm32")]
252
+ pub(crate) fn defer_stdin_readiness() -> bool {
253
+ STDIN_READINESS_DEFERRALS.with(|deferrals| {
254
+ let remaining = deferrals.get();
255
+ deferrals.set(remaining.saturating_sub(1));
256
+ remaining > 0
257
+ })
258
+ }
259
+
242
260
  #[derive(Clone, Copy)]
243
261
  struct ClockSubscription {
244
262
  subscription: Subscription,
@@ -251,6 +269,7 @@ fn call_original_poll<M: MemorySize>(
251
269
  events: WasmPtr<Event, M>,
252
270
  subscription_count: M::Offset,
253
271
  event_count: WasmPtr<M::Offset, M>,
272
+ stdin_deferrals: u64,
254
273
  ) -> Result<i32, RuntimeError> {
255
274
  let Some(original) = env.data().original.clone() else {
256
275
  return Ok(Errno::Notsup as i32);
@@ -262,6 +281,7 @@ fn call_original_poll<M: MemorySize>(
262
281
  Value::I32(offset as i32)
263
282
  }
264
283
  };
284
+ STDIN_READINESS_DEFERRALS.with(|deferrals| deferrals.set(stdin_deferrals));
265
285
  let results = original.call(
266
286
  env,
267
287
  &[
@@ -270,7 +290,9 @@ fn call_original_poll<M: MemorySize>(
270
290
  pointer(subscription_count.into()),
271
291
  pointer(event_count.offset().into()),
272
292
  ],
273
- )?;
293
+ );
294
+ STDIN_READINESS_DEFERRALS.with(|deferrals| deferrals.set(0));
295
+ let results = results?;
274
296
  match results.as_ref() {
275
297
  [Value::I32(errno)] => Ok(*errno),
276
298
  _ => Err(RuntimeError::new(
@@ -302,6 +324,7 @@ fn deterministic_poll_oneoff<M: MemorySize>(
302
324
  let mut originals = Vec::with_capacity(input.len() as usize);
303
325
  let mut clock_subscriptions = Vec::new();
304
326
  let mut has_non_clock = false;
327
+ let mut read_subscriptions = 0;
305
328
  for index in 0..input.len() {
306
329
  let subscription = input
307
330
  .index(index)
@@ -320,6 +343,7 @@ fn deterministic_poll_oneoff<M: MemorySize>(
320
343
  });
321
344
  } else {
322
345
  has_non_clock = true;
346
+ read_subscriptions += u64::from(subscription.type_ == Eventtype::FdRead);
323
347
  }
324
348
  }
325
349
 
@@ -330,6 +354,7 @@ fn deterministic_poll_oneoff<M: MemorySize>(
330
354
  events,
331
355
  subscription_count,
332
356
  event_count,
357
+ read_subscriptions,
333
358
  );
334
359
  }
335
360
 
@@ -355,6 +380,7 @@ fn deterministic_poll_oneoff<M: MemorySize>(
355
380
  events,
356
381
  subscription_count,
357
382
  event_count,
383
+ u64::MAX,
358
384
  );
359
385
  let restore_view = memory.view(&env);
360
386
  let restore_input = subscriptions