AtlatestRepositorysigil-wm
1
/* SPDX-License-Identifier: BSD-3-Clause */2
#include <unistd.h>3
#include <wayland-server-core.h>4
static ssize_t gated_read(int fd,void *buffer,size_t count);5
static const char *gated_socket(struct wl_display *display);6
#define read(...) gated_read(__VA_ARGS__)7
#define wm_send unrecorded_send8
#define wm_input_reply unrecorded_input_reply9
#define wl_display_add_socket_auto gated_socket10
#include "../src/c/host.c"11
#undef wl_display_add_socket_auto12
#undef wm_input_reply13
#undef wm_send14
#undef read16
static atomic_bool hold_commands,commands_held;17
static atomic_int starting_kind;18
static unsigned reply_attempts,reply_refused,reply_accepted;20
int 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;28
}30
int 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;36
}38
int wm_test_start_gate(int kind) {39
atomic_store(&starting_kind,kind);40
return 1;41
}43
/* A copied startup observation exercises retries before the ready event. */44
static 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);55
}57
int 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
}64
}66
/* Pausing command consumption makes saturation independent of thread timing. */67
static 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);78
}80
int 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;92
}94
int 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;101
}103
int wm_test_depth(void) {104
return atomic_load(&bridge.commands.write)-atomic_load(&bridge.commands.read);105
}