Mercurial > hg > xemacs-beta
annotate src/event-unixoid.c @ 5127:a9c41067dd88 ben-lisp-object
more cleanups, terminology clarification, lots of doc work
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Introduction to Allocation):
* internals/internals.texi (Integers and Characters):
* internals/internals.texi (Allocation from Frob Blocks):
* internals/internals.texi (lrecords):
* internals/internals.texi (Low-level allocation):
Rewrite section on allocation of Lisp objects to reflect the new
reality. Remove references to nonexistent XSETINT and XSETCHAR.
modules/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c (allocate_pgconn):
* postgresql/postgresql.c (allocate_pgresult):
* postgresql/postgresql.h (struct Lisp_PGconn):
* postgresql/postgresql.h (struct Lisp_PGresult):
* ldap/eldap.c (allocate_ldap):
* ldap/eldap.h (struct Lisp_LDAP):
Same changes as in src/ dir. See large log there in ChangeLog,
but basically:
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
../hlo/src/ChangeLog addition:
2010-03-05 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (old_alloc_sized_lcrecord):
* alloc.c (very_old_free_lcrecord):
* alloc.c (copy_lisp_object):
* alloc.c (zero_sized_lisp_object):
* alloc.c (zero_nonsized_lisp_object):
* alloc.c (lisp_object_storage_size):
* alloc.c (free_normal_lisp_object):
* alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC):
* alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT):
* alloc.c (Fcons):
* alloc.c (noseeum_cons):
* alloc.c (make_float):
* alloc.c (make_bignum):
* alloc.c (make_bignum_bg):
* alloc.c (make_ratio):
* alloc.c (make_ratio_bg):
* alloc.c (make_ratio_rt):
* alloc.c (make_bigfloat):
* alloc.c (make_bigfloat_bf):
* alloc.c (size_vector):
* alloc.c (make_compiled_function):
* alloc.c (Fmake_symbol):
* alloc.c (allocate_extent):
* alloc.c (allocate_event):
* alloc.c (make_key_data):
* alloc.c (make_button_data):
* alloc.c (make_motion_data):
* alloc.c (make_process_data):
* alloc.c (make_timeout_data):
* alloc.c (make_magic_data):
* alloc.c (make_magic_eval_data):
* alloc.c (make_eval_data):
* alloc.c (make_misc_user_data):
* alloc.c (Fmake_marker):
* alloc.c (noseeum_make_marker):
* alloc.c (size_string_direct_data):
* alloc.c (make_uninit_string):
* alloc.c (make_string_nocopy):
* alloc.c (mark_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (sweep_lcrecords_1):
* alloc.c (malloced_storage_size):
* buffer.c (allocate_buffer):
* buffer.c (compute_buffer_usage):
* buffer.c (DEFVAR_BUFFER_LOCAL_1):
* buffer.c (nuke_all_buffer_slots):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.h (struct buffer_text):
* buffer.h (struct buffer):
* bytecode.c:
* bytecode.c (make_compiled_function_args):
* bytecode.c (size_compiled_function_args):
* bytecode.h (struct compiled_function_args):
* casetab.c (allocate_case_table):
* casetab.h (struct Lisp_Case_Table):
* charset.h (struct Lisp_Charset):
* chartab.c (fill_char_table):
* chartab.c (Fmake_char_table):
* chartab.c (make_char_table_entry):
* chartab.c (copy_char_table_entry):
* chartab.c (Fcopy_char_table):
* chartab.c (put_char_table):
* chartab.h (struct Lisp_Char_Table_Entry):
* chartab.h (struct Lisp_Char_Table):
* console-gtk-impl.h (struct gtk_device):
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h (struct console):
* console-msw-impl.h (struct Lisp_Devmode):
* console-msw-impl.h (struct mswindows_device):
* console-msw-impl.h (struct msprinter_device):
* console-msw-impl.h (struct mswindows_frame):
* console-msw-impl.h (struct mswindows_dialog_id):
* console-stream-impl.h (struct stream_console):
* console-stream.c (stream_init_console):
* console-tty-impl.h (struct tty_console):
* console-tty-impl.h (struct tty_device):
* console-tty.c (allocate_tty_console_struct):
* console-x-impl.h (struct x_device):
* console-x-impl.h (struct x_frame):
* console.c (allocate_console):
* console.c (nuke_all_console_slots):
* console.c (DEFVAR_CONSOLE_LOCAL_1):
* console.c (common_init_complex_vars_of_console):
* data.c (make_weak_list):
* data.c (make_weak_box):
* data.c (make_ephemeron):
* database.c:
* database.c (struct Lisp_Database):
* database.c (allocate_database):
* database.c (finalize_database):
* device-gtk.c (allocate_gtk_device_struct):
* device-impl.h (struct device):
* device-msw.c:
* device-msw.c (mswindows_init_device):
* device-msw.c (msprinter_init_device):
* device-msw.c (finalize_devmode):
* device-msw.c (allocate_devmode):
* device-tty.c (allocate_tty_device_struct):
* device-x.c (allocate_x_device_struct):
* device.c:
* device.c (nuke_all_device_slots):
* device.c (allocate_device):
* dialog-msw.c (handle_question_dialog_box):
* elhash.c:
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (finalize_hash_table):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (Fcopy_hash_table):
* elhash.h (htentry):
* emacs.c (main_1):
* eval.c:
* eval.c (size_multiple_value):
* event-stream.c (finalize_command_builder):
* event-stream.c (allocate_command_builder):
* event-stream.c (free_command_builder):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (event_stream_resignal_wakeup):
* event-stream.c (event_stream_disable_wakeup):
* event-stream.c (event_stream_wakeup_pending_p):
* events.h (struct Lisp_Timeout):
* events.h (struct command_builder):
* extents-impl.h:
* extents-impl.h (struct extent_auxiliary):
* extents-impl.h (struct extent_info):
* extents-impl.h (set_extent_no_chase_aux_field):
* extents-impl.h (set_extent_no_chase_normal_field):
* extents.c:
* extents.c (gap_array_marker):
* extents.c (gap_array):
* extents.c (extent_list_marker):
* extents.c (extent_list):
* extents.c (stack_of_extents):
* extents.c (gap_array_make_marker):
* extents.c (extent_list_make_marker):
* extents.c (allocate_extent_list):
* extents.c (SLOT):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (attach_extent_auxiliary):
* extents.c (size_gap_array):
* extents.c (finalize_extent_info):
* extents.c (allocate_extent_info):
* extents.c (uninit_buffer_extents):
* extents.c (allocate_soe):
* extents.c (copy_extent):
* extents.c (vars_of_extents):
* extents.h:
* faces.c (allocate_face):
* faces.h (struct Lisp_Face):
* faces.h (struct face_cachel):
* file-coding.c:
* file-coding.c (finalize_coding_system):
* file-coding.c (sizeof_coding_system):
* file-coding.c (Fcopy_coding_system):
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (MARKED_SLOT):
* fns.c (size_bit_vector):
* font-mgr.c:
* font-mgr.c (finalize_fc_pattern):
* font-mgr.c (print_fc_pattern):
* font-mgr.c (Ffc_pattern_p):
* font-mgr.c (Ffc_pattern_create):
* font-mgr.c (Ffc_name_parse):
* font-mgr.c (Ffc_name_unparse):
* font-mgr.c (Ffc_pattern_duplicate):
* font-mgr.c (Ffc_pattern_add):
* font-mgr.c (Ffc_pattern_del):
* font-mgr.c (Ffc_pattern_get):
* font-mgr.c (fc_config_create_using):
* font-mgr.c (fc_strlist_to_lisp_using):
* font-mgr.c (fontset_to_list):
* font-mgr.c (Ffc_config_p):
* font-mgr.c (Ffc_config_up_to_date):
* font-mgr.c (Ffc_config_build_fonts):
* font-mgr.c (Ffc_config_get_cache):
* font-mgr.c (Ffc_config_get_fonts):
* font-mgr.c (Ffc_config_set_current):
* font-mgr.c (Ffc_config_get_blanks):
* font-mgr.c (Ffc_config_get_rescan_interval):
* font-mgr.c (Ffc_config_set_rescan_interval):
* font-mgr.c (Ffc_config_app_font_add_file):
* font-mgr.c (Ffc_config_app_font_add_dir):
* font-mgr.c (Ffc_config_app_font_clear):
* font-mgr.c (size):
* font-mgr.c (Ffc_config_substitute):
* font-mgr.c (Ffc_font_render_prepare):
* font-mgr.c (Ffc_font_match):
* font-mgr.c (Ffc_font_sort):
* font-mgr.c (finalize_fc_config):
* font-mgr.c (print_fc_config):
* font-mgr.h:
* font-mgr.h (struct fc_pattern):
* font-mgr.h (XFC_PATTERN):
* font-mgr.h (struct fc_config):
* font-mgr.h (XFC_CONFIG):
* frame-gtk.c (allocate_gtk_frame_struct):
* frame-impl.h (struct frame):
* frame-msw.c (mswindows_init_frame_1):
* frame-x.c (allocate_x_frame_struct):
* frame.c (nuke_all_frame_slots):
* frame.c (allocate_frame_core):
* gc.c:
* gc.c (GC_CHECK_NOT_FREE):
* glyphs.c (finalize_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (Fcolorize_image_instance):
* glyphs.c (allocate_glyph):
* glyphs.c (unmap_subwindow_instance_cache_mapper):
* glyphs.c (register_ignored_expose):
* glyphs.h (struct Lisp_Image_Instance):
* glyphs.h (struct Lisp_Glyph):
* glyphs.h (struct glyph_cachel):
* glyphs.h (struct expose_ignore):
* gui.c (allocate_gui_item):
* gui.h (struct Lisp_Gui_Item):
* keymap.c (struct Lisp_Keymap):
* keymap.c (make_keymap):
* lisp.h:
* lisp.h (struct Lisp_String_Direct_Data):
* lisp.h (struct Lisp_String_Indirect_Data):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR):
* lisp.h (struct weak_box):
* lisp.h (struct ephemeron):
* lisp.h (struct weak_list):
* lrecord.h:
* lrecord.h (struct lrecord_implementation):
* lrecord.h (MC_ALLOC_CALL_FINALIZER):
* lrecord.h (struct lcrecord_list):
* lstream.c (finalize_lstream):
* lstream.c (sizeof_lstream):
* lstream.c (Lstream_new):
* lstream.c (Lstream_delete):
* lstream.h (struct lstream):
* marker.c:
* marker.c (finalize_marker):
* marker.c (compute_buffer_marker_usage):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (compute_charset_usage):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty-impl.h (struct tty_color_instance_data):
* objects-tty-impl.h (struct tty_font_instance_data):
* objects-tty.c (tty_initialize_color_instance):
* objects-tty.c (tty_initialize_font_instance):
* objects.c (finalize_color_instance):
* objects.c (Fmake_color_instance):
* objects.c (finalize_font_instance):
* objects.c (Fmake_font_instance):
* objects.c (reinit_vars_of_objects):
* opaque.c:
* opaque.c (sizeof_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (free_opaque_ptr):
* opaque.h:
* opaque.h (Lisp_Opaque):
* opaque.h (Lisp_Opaque_Ptr):
* print.c (printing_unreadable_lcrecord):
* print.c (external_object_printer):
* print.c (debug_p4):
* process.c (finalize_process):
* process.c (make_process_internal):
* procimpl.h (struct Lisp_Process):
* rangetab.c (Fmake_range_table):
* rangetab.c (Fcopy_range_table):
* rangetab.h (struct Lisp_Range_Table):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* scrollbar.c (compute_scrollbar_instance_usage):
* scrollbar.h (struct scrollbar_instance):
* specifier.c (finalize_specifier):
* specifier.c (sizeof_specifier):
* specifier.c (set_specifier_caching):
* specifier.h (struct Lisp_Specifier):
* specifier.h (struct specifier_caching):
* symeval.h:
* symeval.h (SYMBOL_VALUE_MAGIC_P):
* symeval.h (DEFVAR_SYMVAL_FWD):
* symsinit.h:
* syntax.c (init_buffer_syntax_cache):
* syntax.h (struct syntax_cache):
* toolbar.c:
* toolbar.c (allocate_toolbar_button):
* toolbar.c (update_toolbar_button):
* toolbar.h (struct toolbar_button):
* tooltalk.c (struct Lisp_Tooltalk_Message):
* tooltalk.c (make_tooltalk_message):
* tooltalk.c (struct Lisp_Tooltalk_Pattern):
* tooltalk.c (make_tooltalk_pattern):
* ui-gtk.c:
* ui-gtk.c (allocate_ffi_data):
* ui-gtk.c (emacs_gtk_object_finalizer):
* ui-gtk.c (allocate_emacs_gtk_object_data):
* ui-gtk.c (allocate_emacs_gtk_boxed_data):
* ui-gtk.h:
* window-impl.h (struct window):
* window-impl.h (struct window_mirror):
* window.c (finalize_window):
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (mark_window_as_deleted):
* window.c (make_dummy_parent):
* window.c (compute_window_mirror_usage):
* window.c (compute_window_usage):
Overall point of this change and previous ones in this repository:
(1) Introduce new, clearer terminology: everything other than int
or char is a "record" object, which comes in two types: "normal
objects" and "frob-block objects". Fix up all places that
referred to frob-block objects as "simple", "basic", etc.
(2) Provide an advertised interface for doing operations on Lisp
objects, including creating new types, that is clean and
consistent in its naming, uses the above-referenced terms and
avoids referencing "lrecords", "old lcrecords", etc., which should
hide under the surface.
(3) Make the size_in_bytes and finalizer methods take a
Lisp_Object rather than a void * for consistency with other methods.
(4) Separate finalizer method into finalizer and disksaver, so
that normal finalize methods don't have to worry about disksaving.
Other specifics:
(1) Renaming:
LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER
ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT
implementation->basic_p -> implementation->frob_block_p
ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT
*FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config
*FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern
(the last two changes make the naming of these macros consistent
with the naming of all other macros, since the objects are named
fc-config and fc-pattern with a hyphen)
(2) Lots of documentation fixes in lrecord.h.
(3) Eliminate macros for copying, freeing, zeroing objects, getting
their storage size. Instead, new functions:
zero_sized_lisp_object()
zero_nonsized_lisp_object()
lisp_object_storage_size()
free_normal_lisp_object()
(copy_lisp_object() already exists)
LISP_OBJECT_FROB_BLOCK_P() (actually a macro)
Eliminated:
free_lrecord()
zero_lrecord()
copy_lrecord()
copy_sized_lrecord()
old_copy_lcrecord()
old_copy_sized_lcrecord()
old_zero_lcrecord()
old_zero_sized_lcrecord()
LISP_OBJECT_STORAGE_SIZE()
COPY_SIZED_LISP_OBJECT()
COPY_SIZED_LCRECORD()
COPY_LISP_OBJECT()
ZERO_LISP_OBJECT()
FREE_LISP_OBJECT()
(4) Catch the remaining places where lrecord stuff was used directly
and use the advertised interface, e.g. alloc_sized_lrecord() ->
ALLOC_SIZED_LISP_OBJECT().
(5) Make certain statically-declared pseudo-objects
(buffer_local_flags, console_local_flags) have their lheader
initialized correctly, so things like copy_lisp_object() can work
on them. Make extent_auxiliary_defaults a proper heap object
Vextent_auxiliary_defaults, and make extent auxiliaries dumpable
so that this object can be dumped. allocate_extent_auxiliary()
now just creates the object, and attach_extent_auxiliary()
creates an extent auxiliary and attaches to an extent, like the
old allocate_extent_auxiliary().
(6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h
files but in a macro instead of a file. The purpose is to avoid
duplication when iterating over all the slots in an extent auxiliary.
Use it.
(7) In lstream.c, don't zero out object after allocation because
allocation routines take care of this.
(8) In marker.c, fix a mistake in computing marker overhead.
(9) In print.c, clean up printing_unreadable_lcrecord(),
external_object_printer() to avoid lots of ifdef NEW_GC's.
(10) Separate toolbar-button allocation into a separate
allocate_toolbar_button() function for use in the example code
in lrecord.h.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Fri, 05 Mar 2010 04:08:17 -0600 |
parents | 2ade80e8c640 |
children | 308d34e9f07d |
rev | line source |
---|---|
428 | 1 /* Code shared between all event loops that use select() and have a |
2 different input descriptor for each device. | |
3 Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | |
4 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
5 Copyright (C) 1995 Sun Microsystems, Inc. | |
1268 | 6 Copyright (C) 1995, 1996, 2001, 2002, 2003 Ben Wing. |
428 | 7 |
8 This file is part of XEmacs. | |
9 | |
10 XEmacs is free software; you can redistribute it and/or modify it | |
11 under the terms of the GNU General Public License as published by the | |
12 Free Software Foundation; either version 2, or (at your option) any | |
13 later version. | |
14 | |
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
21 along with XEmacs; see the file COPYING. If not, write to | |
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
23 Boston, MA 02111-1307, USA. */ | |
24 | |
25 /* Synched up with: Not in FSF. */ | |
26 | |
27 /* This file has been Mule-ized. */ | |
28 | |
29 #include <config.h> | |
30 #include "lisp.h" | |
31 | |
872 | 32 #include "console-stream-impl.h" |
33 #include "console-tty-impl.h" | |
1204 | 34 #include "device-impl.h" |
428 | 35 #include "events.h" |
36 #include "lstream.h" | |
37 #include "process.h" | |
38 | |
39 #include "sysdep.h" | |
40 #include "sysfile.h" | |
41 #include "sysproc.h" /* select stuff */ | |
42 #include "systime.h" | |
43 | |
44 /* Mask of bits indicating the descriptors that we wait for input on. | |
45 These work as follows: | |
46 | |
1268 | 47 In event-tty.c we call select() directly on this |
48 to retrieve an event. In event-Xt.c we use | |
49 XtAppAddInput() and the call to select() is down in | |
50 the guts of Xt, but we still use the masks when checking for pending input, even in event-Xt.c. (We can't use XtAppPending() because of the presence of the signal event pipe.) | |
51 | |
428 | 52 input_wait_mask == mask of all file descriptors we select() on, |
53 including TTY/stream console descriptors, | |
54 process descriptors, and the signal event pipe. | |
55 | |
56 non_fake_input_wait_mask == same as input_wait_mask but minus the | |
57 signal event pipe. Also only used in | |
58 event-tty.c. | |
59 | |
60 process_only_mask == only the process descriptors. | |
61 | |
62 tty_only_mask == only the TTY/stream console descriptors. | |
63 */ | |
64 SELECT_TYPE input_wait_mask, non_fake_input_wait_mask; | |
65 SELECT_TYPE process_only_mask, tty_only_mask; | |
66 | |
67 /* This is used to terminate the select(), when an event came in | |
68 through a signal (e.g. window-change or C-g on controlling TTY). */ | |
69 int signal_event_pipe[2]; | |
70 | |
71 int signal_event_pipe_initialized; | |
72 | |
73 int fake_event_occurred; | |
74 | |
1204 | 75 struct console * |
76 find_tty_or_stream_console_from_fd (int fd) | |
77 { | |
78 Lisp_Object concons; | |
79 | |
80 CONSOLE_LOOP (concons) | |
81 { | |
82 struct console *c; | |
83 | |
84 c = XCONSOLE (XCAR (concons)); | |
85 if ((CONSOLE_TTY_P (c) && CONSOLE_TTY_DATA (c)->infd == fd) || | |
86 (CONSOLE_STREAM_P (c) && fileno (CONSOLE_STREAM_DATA (c)->in) == fd)) | |
87 return c; | |
88 } | |
89 | |
90 return 0; | |
91 } | |
92 | |
428 | 93 int |
771 | 94 read_event_from_tty_or_stream_desc (Lisp_Event *event, struct console *con) |
428 | 95 { |
867 | 96 Ichar ch; |
793 | 97 Lisp_Object console = wrap_console (con); |
428 | 98 |
771 | 99 if (CONSOLE_TTY_P (con)) |
867 | 100 ch = Lstream_get_ichar (XLSTREAM (CONSOLE_TTY_DATA (con)->instream)); |
771 | 101 else |
102 { | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4954
diff
changeset
|
103 Ibyte ibyte; |
771 | 104 /* #### Definitely something strange here. We should be setting |
105 the stdio handle unbuffered and reading from it instead of mixing | |
106 stdio and raw io calls. */ | |
4954
70e8a00896e9
fix an obscure crash reading from stream devices
Ben Wing <ben@xemacs.org>
parents:
4780
diff
changeset
|
107 int nread = retry_read (fileno (CONSOLE_STREAM_DATA (con)->in), |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4954
diff
changeset
|
108 &ibyte, 1); |
771 | 109 if (nread <= 0) |
110 ch = -1; | |
4954
70e8a00896e9
fix an obscure crash reading from stream devices
Ben Wing <ben@xemacs.org>
parents:
4780
diff
changeset
|
111 else |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4954
diff
changeset
|
112 ch = ibyte; |
771 | 113 } |
114 | |
115 if (ch < 0) | |
428 | 116 { |
117 /* deleting the console might not be safe right now ... */ | |
118 enqueue_magic_eval_event (io_error_delete_console, console); | |
119 /* but we definitely need to unselect it to avoid infinite | |
120 loops reading EOF's */ | |
121 Fconsole_disable_input (console); | |
122 } | |
123 else | |
124 { | |
4780
2fd201d73a92
Call character_to_event on characters received from XIM, event-Xt.c
Aidan Kehoe <kehoea@parhasard.net>
parents:
4031
diff
changeset
|
125 character_to_event (ch, event, con, use_console_meta_flag, 1); |
428 | 126 event->channel = console; |
127 return 1; | |
128 } | |
129 return 0; | |
130 } | |
131 | |
132 void | |
133 signal_fake_event (void) | |
134 { | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4954
diff
changeset
|
135 Rawbyte rbyte = 0; |
428 | 136 /* We do the write always. Formerly I tried to "optimize" this |
137 by setting a flag indicating whether we're blocking and only | |
138 doing the write in that case, but there is a race condition | |
139 if the signal occurs after we've checked for the signal | |
140 occurrence (which could occur in many places throughout | |
141 an iteration of the command loop, e.g. in status_notify()), | |
142 but before we set the blocking flag. | |
143 | |
771 | 144 This should be OK as long as write() is reentrant, which I'm fairly |
145 sure it is since it's a system call. */ | |
428 | 146 |
147 if (signal_event_pipe_initialized) | |
148 /* In case a signal comes through while we're dumping */ | |
149 { | |
150 int old_errno = errno; | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4954
diff
changeset
|
151 retry_write (signal_event_pipe[1], &rbyte, 1); |
428 | 152 errno = old_errno; |
153 } | |
154 } | |
155 | |
156 void | |
157 drain_signal_event_pipe (void) | |
158 { | |
5016
2ade80e8c640
enable more warnings and fix them
Ben Wing <ben@xemacs.org>
parents:
4954
diff
changeset
|
159 Rawbyte chars[128]; |
428 | 160 /* The input end of the pipe has been set to non-blocking. */ |
771 | 161 while (retry_read (signal_event_pipe[0], chars, sizeof (chars)) > 0) |
428 | 162 ; |
163 } | |
164 | |
1204 | 165 void |
166 drain_tty_devices (void) | |
167 { | |
168 Lisp_Object devcons, concons; | |
169 CONSOLE_LOOP (concons) | |
170 { | |
171 struct console *con = XCONSOLE (XCAR (concons)); | |
172 if (!con->input_enabled) | |
173 continue; | |
174 | |
175 CONSOLE_DEVICE_LOOP (devcons, con) | |
176 { | |
177 struct device *d = XDEVICE (XCAR (devcons)); | |
178 if (DEVICE_TTY_P (d)) | |
179 { | |
180 SELECT_TYPE temp_mask; | |
181 int infd = DEVICE_INFD (d); | |
182 | |
183 FD_ZERO (&temp_mask); | |
184 FD_SET (infd, &temp_mask); | |
185 | |
186 while (1) | |
187 { | |
188 Lisp_Object event; | |
189 | |
190 if (!poll_fds_for_input (temp_mask)) | |
191 break; | |
192 | |
193 event = Fmake_event (Qnil, Qnil); | |
194 if (!read_event_from_tty_or_stream_desc (XEVENT (event), | |
195 con)) | |
196 /* EOF, or something ... */ | |
197 break; | |
198 | |
199 /* queue the read event to be read for real later. */ | |
200 enqueue_dispatch_event (event); | |
201 } | |
202 } | |
203 } | |
204 } | |
205 } | |
206 | |
428 | 207 int |
208 event_stream_unixoid_select_console (struct console *con) | |
209 { | |
210 int infd; | |
211 | |
212 if (CONSOLE_STREAM_P (con)) | |
213 infd = fileno (CONSOLE_STREAM_DATA (con)->in); | |
214 else | |
215 { | |
216 assert (CONSOLE_TTY_P (con)); | |
217 infd = CONSOLE_TTY_DATA (con)->infd; | |
218 } | |
219 | |
220 assert (infd >= 0); | |
221 | |
222 FD_SET (infd, &input_wait_mask); | |
223 FD_SET (infd, &non_fake_input_wait_mask); | |
224 FD_SET (infd, &tty_only_mask); | |
225 return infd; | |
226 } | |
227 | |
228 int | |
229 event_stream_unixoid_unselect_console (struct console *con) | |
230 { | |
231 int infd; | |
232 | |
233 if (CONSOLE_STREAM_P (con)) | |
234 infd = fileno (CONSOLE_STREAM_DATA (con)->in); | |
235 else | |
236 { | |
237 assert (CONSOLE_TTY_P (con)); | |
238 infd = CONSOLE_TTY_DATA (con)->infd; | |
239 } | |
240 | |
241 assert (infd >= 0); | |
242 | |
243 FD_CLR (infd, &input_wait_mask); | |
244 FD_CLR (infd, &non_fake_input_wait_mask); | |
245 FD_CLR (infd, &tty_only_mask); | |
246 return infd; | |
247 } | |
248 | |
249 static int | |
440 | 250 get_process_infd (Lisp_Process *p) |
428 | 251 { |
853 | 252 Lisp_Object instr, outstr, errstr; |
253 get_process_streams (p, &instr, &outstr, &errstr); | |
428 | 254 assert (!NILP (instr)); |
255 return filedesc_stream_fd (XLSTREAM (instr)); | |
256 } | |
257 | |
853 | 258 static int |
259 get_process_errfd (Lisp_Process *p) | |
428 | 260 { |
853 | 261 Lisp_Object instr, outstr, errstr; |
262 get_process_streams (p, &instr, &outstr, &errstr); | |
263 if (!NILP (errstr)) | |
264 return filedesc_stream_fd (XLSTREAM (errstr)); | |
265 else | |
266 return -1; | |
428 | 267 } |
268 | |
853 | 269 void |
270 event_stream_unixoid_select_process (Lisp_Process *proc, int doin, int doerr, | |
271 int *infd, int *errfd) | |
428 | 272 { |
853 | 273 if (doin) |
274 { | |
275 *infd = get_process_infd (proc); | |
276 FD_SET (*infd, &input_wait_mask); | |
277 FD_SET (*infd, &non_fake_input_wait_mask); | |
278 FD_SET (*infd, &process_only_mask); | |
279 } | |
280 | |
281 if (doerr) | |
282 { | |
283 *errfd = get_process_errfd (proc); | |
428 | 284 |
853 | 285 if (*errfd >= 0) |
286 { | |
287 FD_SET (*errfd, &input_wait_mask); | |
288 FD_SET (*errfd, &non_fake_input_wait_mask); | |
289 FD_SET (*errfd, &process_only_mask); | |
290 } | |
291 } | |
292 } | |
293 | |
294 void | |
295 event_stream_unixoid_unselect_process (Lisp_Process *proc, int doin, int doerr, | |
296 int *infd, int *errfd) | |
297 { | |
298 if (doin) | |
299 { | |
300 *infd = get_process_infd (proc); | |
301 FD_CLR (*infd, &input_wait_mask); | |
302 FD_CLR (*infd, &non_fake_input_wait_mask); | |
303 FD_CLR (*infd, &process_only_mask); | |
304 } | |
305 | |
306 if (doerr) | |
307 { | |
308 *errfd = get_process_errfd (proc); | |
309 | |
310 if (*errfd >= 0) | |
311 { | |
312 FD_CLR (*errfd, &input_wait_mask); | |
313 FD_CLR (*errfd, &non_fake_input_wait_mask); | |
314 FD_CLR (*errfd, &process_only_mask); | |
315 } | |
316 } | |
428 | 317 } |
318 | |
319 int | |
320 poll_fds_for_input (SELECT_TYPE mask) | |
321 { | |
322 EMACS_TIME sometime; | |
323 EMACS_SELECT_TIME select_time; | |
324 SELECT_TYPE temp_mask; | |
325 int retval; | |
326 | |
327 while (1) | |
328 { | |
329 EMACS_SET_SECS_USECS (sometime, 0, 0); | |
330 EMACS_TIME_TO_SELECT_TIME (sometime, select_time); | |
331 temp_mask = mask; | |
332 /* To effect a poll, tell select() to block for zero seconds. */ | |
333 retval = select (MAXDESC, &temp_mask, 0, 0, &select_time); | |
334 if (retval >= 0) | |
335 return retval; | |
336 if (errno != EINTR) | |
337 { | |
338 /* Something went seriously wrong; don't abort since maybe | |
339 the TTY just died at the wrong time. */ | |
442 | 340 stderr_out ("xemacs: select failed: errno = %d\n", errno); |
428 | 341 return 0; |
342 } | |
343 /* else, we got interrupted by a signal, so try again. */ | |
344 } | |
345 | |
1204 | 346 RETURN_NOT_REACHED (0); |
428 | 347 } |
348 | |
349 /****************************************************************************/ | |
350 /* Unixoid (file descriptors based) process I/O streams routines */ | |
351 /****************************************************************************/ | |
352 | |
853 | 353 void |
354 event_stream_unixoid_create_io_streams (void* inhandle, void* outhandle, | |
355 void *errhandle, Lisp_Object* instream, | |
356 Lisp_Object* outstream, | |
357 Lisp_Object* errstream, | |
358 USID* in_usid, | |
359 USID* err_usid, | |
360 int flags) | |
428 | 361 { |
853 | 362 int infd, outfd, errfd; |
428 | 363 /* Decode inhandle and outhandle. Their meaning depends on |
364 the process implementation being used. */ | |
4031 | 365 /* We are passed plain old file descs, which are ints, so */ |
366 /* if sizeof(EMACS_INT) > sizeof(int) it's OK. */ | |
367 infd = (EMACS_INT) inhandle; | |
368 outfd = (EMACS_INT) outhandle; | |
369 errfd = (EMACS_INT) errhandle; | |
428 | 370 |
371 *instream = (infd >= 0 | |
372 ? make_filedesc_input_stream (infd, 0, -1, 0) | |
373 : Qnil); | |
374 | |
375 *outstream = (outfd >= 0 | |
376 ? make_filedesc_output_stream (outfd, 0, -1, LSTR_BLOCKED_OK) | |
377 : Qnil); | |
378 | |
853 | 379 *errstream = (errfd >= 0 |
380 ? make_filedesc_input_stream (errfd, 0, -1, 0) | |
381 : Qnil); | |
382 | |
428 | 383 /* FLAGS is process->pty_flag for UNIX_PROCESSES */ |
384 if ((flags & STREAM_PTY_FLUSHING) && outfd >= 0) | |
385 { | |
867 | 386 Ibyte eof_char = get_eof_char (outfd); |
428 | 387 int pty_max_bytes = get_pty_max_bytes (outfd); |
853 | 388 filedesc_stream_set_pty_flushing (XLSTREAM (*outstream), pty_max_bytes, |
389 eof_char); | |
428 | 390 } |
391 | |
853 | 392 *in_usid = FD_TO_USID (infd); |
393 *err_usid = FD_TO_USID (errfd); | |
428 | 394 } |
395 | |
853 | 396 void |
397 event_stream_unixoid_delete_io_streams (Lisp_Object instream, | |
398 Lisp_Object outstream, | |
399 Lisp_Object errstream, | |
400 USID *in_usid, | |
401 USID *err_usid) | |
428 | 402 { |
853 | 403 int in = (NILP (instream) ? -1 |
428 | 404 : filedesc_stream_fd (XLSTREAM (instream))); |
853 | 405 int out = (NILP (outstream) ? -1 |
428 | 406 : filedesc_stream_fd (XLSTREAM (outstream))); |
853 | 407 int err = (NILP (errstream) ? -1 |
408 : filedesc_stream_fd (XLSTREAM (errstream))); | |
428 | 409 |
410 if (in >= 0) | |
771 | 411 retry_close (in); |
428 | 412 if (out != in && out >= 0) |
771 | 413 retry_close (out); |
853 | 414 if (err != in && err != out && err >= 0) |
415 retry_close (err); | |
428 | 416 |
853 | 417 *in_usid = FD_TO_USID (in); |
418 *err_usid = FD_TO_USID (err); | |
428 | 419 } |
420 | |
421 | |
422 void | |
423 init_event_unixoid (void) | |
424 { | |
425 /* Do this first; the init_event_*_late() functions | |
426 pay attention to it. */ | |
427 if (pipe (signal_event_pipe) < 0) | |
428 { | |
429 perror ("XEmacs: can't open pipe"); | |
430 exit (-1); | |
431 } | |
432 signal_event_pipe_initialized = 1; | |
433 | |
434 /* Set it non-blocking so we can drain its output. */ | |
435 set_descriptor_non_blocking (signal_event_pipe[0]); | |
436 | |
437 /* Also set the write descriptor non-blocking so we don't | |
438 hang in case a long time passes between times when | |
439 we drain the pipe. */ | |
440 set_descriptor_non_blocking (signal_event_pipe[1]); | |
441 | |
442 /* WARNING: In order for the signal-event pipe to work correctly | |
443 and not cause lockups, the following need to be followed: | |
444 | |
445 1) event_pending_p() must ignore input on the signal-event pipe. | |
446 2) As soon as next_event() notices input on the signal-event | |
447 pipe, it must drain it. */ | |
448 FD_ZERO (&input_wait_mask); | |
449 FD_ZERO (&non_fake_input_wait_mask); | |
450 FD_ZERO (&process_only_mask); | |
451 FD_ZERO (&tty_only_mask); | |
452 | |
453 FD_SET (signal_event_pipe[0], &input_wait_mask); | |
454 } |