summaryrefslogtreecommitdiff
path: root/src/c_client.py
diff options
context:
space:
mode:
authorPeter Harris <pharris@opentext.com>2021-02-01 19:45:28 -0500
committerPeter Harris <pharris@opentext.com>2021-06-04 14:31:13 +0000
commit21414e7c447f18224c577ed5e32bd5d6e45c44f9 (patch)
tree0002140c8f51e0cf23d186f6f6a3ec362586addd /src/c_client.py
parent4b0d9d3868aad8d5f4266821e9eda586e6c2bfa7 (diff)
Fix writev emulation on Windows
There are at least two bugs in the previous implementation: - If an early iovec is partially written, there can be a gap of missing data (as a later iovec will be started before the early iovec is completed). - If a late iovec returns WSAEWOULDBLOCK, *vector and *count are not updated, leading to a re-send of the entire request. Move the *vector update into the send() loop to update piecemeal as individual iovecs are sent. Example program that demonstrates the issue (this program should run forever after these bugs have been fixed): #include <stdio.h> #include <stdlib.h> #include "xcb.h" // Non-cryptographic random number generator from http://burtleburtle.net/bob/rand/smallprng.html // because Microsoft's random number generators either have a too small RAND_MAX or are too slow typedef struct ranctx { uint32_t a; uint32_t b; uint32_t c; uint32_t d; } ranctx; static uint32_t ranval(ranctx *x); static void raninit(ranctx *x, uint32_t seed); #define MAX_PROP_LEN (128 * 1024) int main(int argc, char *argv[]) { uint32_t seed = 0x12345678; if (argc > 1) { seed = strtoul(argv[1], NULL, 0); } ranctx ran; raninit(&ran, seed); xcb_connection_t *c = xcb_connect(NULL, NULL); if (!c || xcb_connection_has_error(c)) { printf("Cannot connect to $DISPLAY\n"); return 1; } const xcb_setup_t *setup = xcb_get_setup(c); char *buf = malloc(MAX_PROP_LEN + 8); // plus a bit of slack so we can run random values off the end if (!buf) { printf("oom\n"); return 1; } for (uint32_t i=0; i < (MAX_PROP_LEN + 3) / 4; i++) { ((uint32_t *)buf)[i] = ranval(&ran); } xcb_window_t win = xcb_generate_id(c); xcb_create_window(c, 0, win, xcb_setup_roots_iterator(setup).data[0].root, 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, 0, 0, NULL); printf("Created window 0x%X\n", win); for (;;) { xcb_flush(c); xcb_generic_event_t *ev = xcb_poll_for_event(c); if (ev) { if (ev->response_type == 0) { xcb_generic_error_t *err = (xcb_generic_error_t *)ev; printf("Unexpected X Error %d\n", err->error_code); printf(" Sequence %d\n", err->sequence); printf(" Resource ID 0x%X\n", err->resource_id); printf(" Opcode: %d.%d\n", err->major_code, err->minor_code); return 1; } printf("Unexpected X Event %d\n", ev->response_type); return 1; } uint32_t siz = ranval(&ran) % MAX_PROP_LEN + 1; xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, XCB_ATOM_STRING, XCB_ATOM_STRING, 8, siz, buf); } return 0; } #define rot(x,k) (((x)<<(k))|((x)>>(32-(k)))) static uint32_t ranval(ranctx *x) { uint32_t e = x->a - rot(x->b, 27); x->a = x->b ^ rot(x->c, 17); x->b = x->c + x->d; x->c = x->d + e; x->d = e + x->a; return x->d; } static void raninit(ranctx *x, uint32_t seed) { uint32_t i; x->a = 0xf1ea5eed, x->b = x->c = x->d = seed; for (i = 0; i<20; ++i) { (void)ranval(x); } } Signed-off-by: Peter Harris <pharris@opentext.com>
Diffstat (limited to 'src/c_client.py')
0 files changed, 0 insertions, 0 deletions