From: "edelsohn (David Edelsohn)" Date: 2013-03-29T03:06:26+09:00 Subject: [ruby-core:53809] [Backport 200 - Backport #8174] AIX header file conflict with rb_hook_list_struct Issue #8174 has been updated by edelsohn (David Edelsohn). Nakada-san, The patch checked in to ruby-trunk was not the same as the one that you proposed. The patch #undefs the macros after including poll.h. # ifdef _AIX # define reqevents events # define rtnevents revents # endif # include # ifdef _AIX # undef reqevents # undef rtnevents # endif With changeset r39987, AIX remains broken. Your original patch redefined the identifiers throughout the entire file. The committed patch exchanges some names within poll.h but does not satisfy identifiers used within thread.c With the original proposed patch, thread.i looks like: struct pollfd { long fd; ushort events; ushort revents; }; #define events reqevents #define revents rtnevents pollfds[0].fd = timer_thread_pipe[0]; pollfds[0].events = 0x0001; pollfds[1].fd = timer_thread_pipe_low[0]; pollfds[1].events = 0x0001; do { rb_thread_t * const _th = (th); struct rb_vm_tag _tag; _tag.tag = 0; _tag. prev = _th->tag; _th->tag = &_tag;; if ((state = _setjmp(_th->tag->buf)) == 0) { do if (_setjmp((th)->root_jmpbuf) == 0) { { if (!th->first_func) { do { ((p roc)) = (rb_proc_t*)(((struct RData*)((th->first_proc)))->data); } while (0); th ->errinfo = ((VALUE)RUBY_Qnil); th->root_lep = rb_vm_ep_local_ep(proc->block.ep) ; th->root_svar = ((VALUE)RUBY_Qnil); do { if ((__builtin_expect((ruby_vm_event_ flags & (0x0400)), 0))) { if (((th)->event_hooks.events | (th)->vm->event_hooks. events) & (0x0400)) { struct rb_trace_arg_struct trace_arg; trace_arg.event = (0 x0400); trace_arg.th = (th); trace_arg.cfp = (trace_arg.th)->cfp; trace_arg.self = (th->self); trace_arg.id = (0); trace_arg.klass = (0); trace_arg.data = (((VA LUE)RUBY_Qundef)); trace_arg.path = ((VALUE)RUBY_Qundef); trace_arg.klass_solved = 0; if (0) rb_threadptr_exec_event_hooks_and_pop_frame(&trace_arg); else rb_th readptr_exec_event_hooks(&trace_arg); } } } while (0); th->value = rb_vm_invoke_ proc(th, proc, (int)((((struct RBasic*)(args))->flags & (((VALUE)1)<<(12 +1))) ? (long)((((struct RBasic*)(args))->flags >> (12 +3)) & (((((VALUE)1)<<(12 +4))|( ((VALUE)1)<<(12 +3))) >> (12 +3))) : ((struct RArray*)(args))->as.heap.len), ((( (struct RBasic*)(args))->flags & (((VALUE)1)<<(12 +1))) ? ((struct RArray*)(args ))->as.ary : ((struct RArray*)(args))->as.heap.ptr), 0); do { if ((__builtin_exp ect((ruby_vm_event_flags & (0x0800)), 0))) { if (((th)->event_hooks.events | (th )->vm->event_hooks.events) & (0x0800)) { struct rb_trace_arg_struct trace_arg; t race_arg.event = (0x0800); trace_arg.th = (th); trace_arg.cfp = (trace_arg.th)-> cfp; trace_arg.self = (th->self); trace_arg.id = (0); trace_arg.klass = (0); tra ce_arg.data = (((VALUE)RUBY_Qundef)); trace_arg.path = ((VALUE)RUBY_Qundef); tra ce_arg.klass_solved = 0; if (0) rb_threadptr_exec_event_hooks_and_pop_frame(&tra ce_arg); else rb_threadptr_exec_event_hooks(&trace_arg); } } } while (0); } else { th->value = (*th->first_func)((void *)args); } }; } else { rb_fiber_start(); } while (0) because the pollfd struct declaration is affected in the header to use the correct member names directly. With the current sources, the pollfd struct declaration is modifier, but the rest of the file uses the wrong member names: struct pollfd { long fd; ushort events; ushort revents; }; #define events reqevents #define revents rtnevents #undef reqevents #undef rtnevents pollfds[0].fd = timer_thread_pipe[0]; pollfds[0].reqevents = 0x0001; pollfds[1].fd = timer_thread_pipe_low[0]; pollfds[1].reqevents = 0x0001; if ((state = _setjmp(_th->tag->buf)) == 0) { do if (_setjmp((th)->root_jmpbuf) == 0) { { if (!th->first_func) { do { ((p roc)) = (rb_proc_t*)(((struct RData*)((th->first_proc)))->data); } while (0); th ->errinfo = ((VALUE)RUBY_Qnil); th->root_lep = rb_vm_ep_local_ep(proc->block.ep) ; th->root_svar = ((VALUE)RUBY_Qnil); do { if ((__builtin_expect((ruby_vm_event_ flags & (0x0400)), 0))) { if (((th)->event_hooks.reqevents | (th)->vm->event_hoo ks.reqevents) & (0x0400)) { struct rb_trace_arg_struct trace_arg; trace_arg.even t = (0x0400); trace_arg.th = (th); trace_arg.cfp = (trace_arg.th)->cfp; trace_ar g.self = (th->self); trace_arg.id = (0); trace_arg.klass = (0); trace_arg.data = (((VALUE)RUBY_Qundef)); trace_arg.path = ((VALUE)RUBY_Qundef); trace_arg.klass_ solved = 0; if (0) rb_threadptr_exec_event_hooks_and_pop_frame(&trace_arg); else rb_threadptr_exec_event_hooks(&trace_arg); } } } while (0); th->value = rb_vm_i nvoke_proc(th, proc, (int)((((struct RBasic*)(args))->flags & (((VALUE)1)<<(12 + 1))) ? (long)((((struct RBasic*)(args))->flags >> (12 +3)) & (((((VALUE)1)<<(12 +4))|(((VALUE)1)<<(12 +3))) >> (12 +3))) : ((struct RArray*)(args))->as.heap.len ), ((((struct RBasic*)(args))->flags & (((VALUE)1)<<(12 +1))) ? ((struct RArray* )(args))->as.ary : ((struct RArray*)(args))->as.heap.ptr), 0); do { if ((__built in_expect((ruby_vm_event_flags & (0x0800)), 0))) { if (((th)->event_hooks.reqeve nts | (th)->vm->event_hooks.reqevents) & (0x0800)) { struct rb_trace_arg_struct trace_arg; trace_arg.event = (0x0800); trace_arg.th = (th); trace_arg.cfp = (tra ce_arg.th)->cfp; trace_arg.self = (th->self); trace_arg.id = (0); trace_arg.klas s = (0); trace_arg.data = (((VALUE)RUBY_Qundef)); trace_arg.path = ((VALUE)RUBY_ Qundef); trace_arg.klass_solved = 0; if (0) rb_threadptr_exec_event_hooks_and_po p_frame(&trace_arg); else rb_threadptr_exec_event_hooks(&trace_arg); } } } while (0); } else { th->value = (*th->first_func)((void *)args); } }; } else { rb_fib er_start(); } while (0) and there is no member reqevents in struct pollfd. ---------------------------------------- Backport #8174: AIX header file conflict with rb_hook_list_struct https://bugs.ruby-lang.org/issues/8174#change-38012 Author: edelsohn (David Edelsohn) Status: Assigned Priority: Normal Assignee: nagachika (Tomoyuki Chikanaga) Category: Target version: =begin rb_hook_list_struct defines a member "events": typedef struct rb_hook_list_struct { struct rb_event_hook_struct *hooks; rb_event_flag_t events; int need_clean; } rb_hook_list_t; AIX defines a macro "events" in sys/poll.h: struct pollfd { long fd; /* file descriptor or file ptr */ ushort reqevents; /* requested events */ ushort rtnevents; /* returned events */ }; #define events reqevents /* SVR3,4 pollfd member name */ #define revents rtnevents /* SVR3,4 pollfd member name */ Ruby thread.c includes sys/poll.c via ruby/io.h. This renames the structure member when referenced through EXEC_EVENT_HOOK, e.g., if ((state = EXEC_TAG()) == 0) { SAVE_ROOT_JMPBUF(th, { if (!th->first_func) { GetProcPtr(th->first_proc, proc); th->errinfo = Qnil; th->root_lep = rb_vm_ep_local_ep(proc->block.ep); th->root_svar = Qnil; EXEC_EVENT_HOOK(th, RUBY_EVENT_THREAD_BEGIN, th->self, 0, 0, Qundef); th->value = rb_vm_invoke_proc(th, proc, (int)RARRAY_LEN(args), RARRAY_PTR(args), 0); EXEC_EVENT_HOOK(th, RUBY_EVENT_THREAD_END, th->self, 0, 0, Qundef); } This makes the compiler unhappy: compiling /usr/gnu/src/ruby-2.0.0-p0/thread.c /usr/gnu/src/ruby-2.0.0-p0/thread.c: In function 'thread_start_func_2': /usr/gnu/src/ruby-2.0.0-p0/thread.c:496:6: error: 'rb_hook_list_t' has no member named 'reqevents' /usr/gnu/src/ruby-2.0.0-p0/thread.c:496:6: error: 'rb_hook_list_t' has no member named 'reqevents' /usr/gnu/src/ruby-2.0.0-p0/thread.c:496:6: error: 'rb_hook_list_t' has no member named 'reqevents' /usr/gnu/src/ruby-2.0.0-p0/thread.c:496:6: error: 'rb_hook_list_t' has no member named 'reqevents' /usr/gnu/src/ruby-2.0.0-p0/thread.c: In function 'rb_threadptr_execute_interrupts': /usr/gnu/src/ruby-2.0.0-p0/thread.c:1917:6: error: 'rb_hook_list_t' has no member named 'reqevents' /usr/gnu/src/ruby-2.0.0-p0/thread.c:1917:6: error: 'rb_hook_list_t' has no member named 'reqevents' Because Ruby only uses fd member revents, one option is to change include/ruby/io.h # diff #include "ruby/config.h" #if defined(HAVE_POLL) # include +# undef events # define RB_WAITFD_IN POLLIN # define RB_WAITFD_PRI POLLPRI # define RB_WAITFD_OUT POLLOUT =end -- http://bugs.ruby-lang.org/