AtlatestRepositorysigil-wm

sigil-wm / tree / testinput-queue-gate.c

1/* SPDX-License-Identifier: BSD-3-Clause */
2#include <unistd.h>
3#include <wayland-server-core.h>
4static ssize_t gated_read(int fd,void *buffer,size_t count);
5static const char *gated_socket(struct wl_display *display);
6#define read(...) gated_read(__VA_ARGS__)
7#define wm_send unrecorded_send
8#define wm_input_reply unrecorded_input_reply
9#define wl_display_add_socket_auto gated_socket
10#include "../src/c/host.c"
11#undef wl_display_add_socket_auto
12#undef wm_input_reply
13#undef wm_send
14#undef read
16static atomic_bool hold_commands,commands_held;
17static atomic_int starting_kind;
18static unsigned reply_attempts,reply_refused,reply_accepted;
20int wm_send(const struct wm_message *message) {
21 int result=unrecorded_send(message);
22 if(message && message->word[0]==11) {
23 reply_attempts++;
24 if(result) reply_accepted++;
25 else reply_refused++;
26 }
27 return result;
30int wm_input_reply(const struct wm_message *message,int kind) {
31 int result=unrecorded_input_reply(message,kind);
32 reply_attempts++;
33 if(result==WM_SEND_ACCEPTED) reply_accepted++;
34 else reply_refused++;
35 return result;
38int wm_test_start_gate(int kind) {
39 atomic_store(&starting_kind,kind);
40 return 1;
43/* A copied startup observation exercises retries before the ready event. */
44static const char *gated_socket(struct wl_display *display) {
45 int kind=atomic_load(&starting_kind);
46 if(kind) {
47 emit((struct wm_message){.word={kind,777,1,now_ms(),kind==30 ? 30 : kind==31 ? 272 : 0,1,0,0,1,1}});
48 uint64_t deadline=now_ms()+3000;
49 while(atomic_load(&starting_kind) && now_ms()<deadline) {
50 struct timespec delay={.tv_nsec=500000};
51 nanosleep(&delay,NULL);
52 }
53 }
54 return wl_display_add_socket_auto(display);
57int wm_test_reply_stat(int index) {
58 switch(index) {
59 case 0: return reply_attempts;
60 case 1: return reply_refused;
61 case 2: return reply_accepted;
62 default: return -1;
63 }
66/* Pausing command consumption makes saturation independent of thread timing. */
67static ssize_t gated_read(int fd,void *buffer,size_t count) {
68 if(fd==bridge.command_fd && atomic_load(&hold_commands)) {
69 atomic_store(&commands_held,true);
70 uint64_t deadline=now_ms()+3000;
71 while(atomic_load(&hold_commands) && now_ms()<deadline) {
72 struct timespec delay={.tv_nsec=500000};
73 nanosleep(&delay,NULL);
74 }
75 atomic_store(&commands_held,false);
76 }
77 return read(fd,buffer,count);
80int wm_test_gate(int hold) {
81 atomic_store(&hold_commands,hold!=0);
82 if(!hold) return 1;
83 struct wm_message command={.word={14,3}};
84 if(!wm_send(&command)) return 0;
85 uint64_t deadline=now_ms()+1000;
86 while(!atomic_load(&commands_held)) {
87 if(now_ms()>=deadline) return 0;
88 struct timespec delay={.tv_nsec=500000};
89 nanosleep(&delay,NULL);
90 }
91 return 1;
94int wm_test_queued(int kind) {
95 if(!atomic_load(&commands_held)) return -1;
96 unsigned first=atomic_load(&bridge.commands.read),last=atomic_load(&bridge.commands.write);
97 unsigned count=0;
98 for(unsigned i=first;i!=last;i++)
99 if(!kind || bridge.commands.entries[i%QUEUE_SIZE].word[0]==kind) count++;
100 return count;
103int wm_test_depth(void) {
104 return atomic_load(&bridge.commands.write)-atomic_load(&bridge.commands.read);