/[slime]/slime/swank-backend.lisp
ViewVC logotype

Contents of /slime/swank-backend.lisp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.67 - (show annotations)
Tue Sep 14 16:01:07 2004 UTC (9 years, 7 months ago) by mbaringer
Branch: MAIN
Changes since 1.66: +58 -12 lines
2004-09-14  Marco Baringer  <mb@bese.it>

	* swank-backend.lisp (inspector, make-default-inspector): Add an
	INSPECTOR object argument to the inspector protocol. This allows
	implementations to provide more information regarding cretain
	objects which can't be, or simply aren't, inspected using the
	generic inspector implementation. also export inspect-for-emacs
	and related symbols from the backend package.
	(make-default-inspector): New function.

	* swank.lisp (inspected-parts): Rename to inspect-for-emacs and
	add an inspector argument. Move inspect-for-emacs to
	swank-backend.lisp, leave only the default implementations.

	* swank-openml.lisp, swank-sbcl.lisp, swank-allegro.lisp,
	swank-cmucl.lisp, swank-lispworks.lisp (inspected-parts): Rename
	and change argument list. Many of the inspected-parts methods were
	being clobbered by the inspected-parts in swank.lisp, now that
	they're being used the return values have been updated for the new
	inspect-for-emacs API.
1 ;;;; -*- Mode: lisp; indent-tabs-mode: nil; outline-regexp: ";;;;;*" -*-
2 ;;;
3 ;;; slime-backend.lisp --- SLIME backend interface.
4 ;;;
5 ;;; Created by James Bielman in 2003. Released into the public domain.
6 ;;;
7 ;;; This file defines the functions that must be implemented
8 ;;; separately for each Lisp. Each is declared as a generic function
9 ;;; for which swank-<implementation>.lisp provides methods.
10
11 (defpackage :swank-backend
12 (:use :common-lisp)
13 (:export #:sldb-condition
14 #:original-condition
15 #:compiler-condition
16 #:message
17 #:short-message
18 #:condition
19 #:severity
20 #:location
21 #:location-p
22 #:location-buffer
23 #:location-position
24 #:position-p
25 #:position-pos
26 #:print-output-to-string
27 #:quit-lisp
28 #:references
29 #:unbound-slot-filler
30 ;; inspector related symbols
31 #:inspector
32 #:inspect-for-emacs
33 #:raw-inspection
34 #:fancy-inspection
35 ))
36
37 (defpackage :swank-mop
38 (:use)
39 (:export
40 ;; classes
41 #:standard-generic-function
42 #:standard-slot-definition
43 #:standard-method
44 #:standard-class
45 ;; standard-class readers
46 #:class-default-initargs
47 #:class-direct-default-initargs
48 #:class-direct-slots
49 #:class-direct-subclasses
50 #:class-direct-superclasses
51 #:class-finalized-p
52 #:class-name
53 #:class-precedence-list
54 #:class-prototype
55 #:class-slots
56 ;; generic function readers
57 #:generic-function-argument-precedence-order
58 #:generic-function-declarations
59 #:generic-function-lambda-list
60 #:generic-function-methods
61 #:generic-function-method-class
62 #:generic-function-method-combination
63 #:generic-function-name
64 ;; method readers
65 #:method-generic-function
66 #:method-function
67 #:method-lambda-list
68 #:method-specializers
69 #:method-qualifiers
70 ;; slot readers
71 #:slot-definition-allocation
72 #:slot-definition-documentation
73 #:slot-definition-initargs
74 #:slot-definition-initform
75 #:slot-definition-initfunction
76 #:slot-definition-name
77 #:slot-definition-type
78 #:slot-definition-readers
79 #:slot-definition-writers))
80
81 (defun swank-backend::import-to-swank-mop (symbol-list)
82 (dolist (sym symbol-list)
83 (let* ((swank-mop-sym (find-symbol (symbol-name sym) :swank-mop)))
84 (when swank-mop-sym
85 (unintern swank-mop-sym :swank-mop))
86 (import sym :swank-mop)
87 (export sym :swank-mop))))
88
89 (in-package :swank-backend)
90
91
92 ;;;; Metacode
93
94 (defparameter *interface-functions* '()
95 "The names of all interface functions.")
96
97 (defparameter *unimplemented-interfaces* '()
98 "List of interface functions that are not implemented.
99 DEFINTERFACE adds to this list and DEFIMPLEMENTATION removes.")
100
101 (defmacro definterface (name args documentation &rest default-body)
102 "Define an interface function for the backend to implement.
103 A generic function is defined with NAME, ARGS, and DOCUMENTATION.
104
105 If a DEFAULT-BODY is supplied then NO-APPLICABLE-METHOD is specialized
106 to execute the body if the backend doesn't provide a specific
107 implementation.
108
109 Backends implement these functions using DEFIMPLEMENTATION."
110 (check-type documentation string "a documentation string")
111 (flet ((gen-default-impl ()
112 (let ((received-args (gensym "ARGS-")))
113 `(defmethod ,name ,args ,@default-body))))
114 `(progn (defgeneric ,name ,args (:documentation ,documentation))
115 (pushnew ',name *interface-functions*)
116 ,(if (null default-body)
117 `(pushnew ',name *unimplemented-interfaces*)
118 (gen-default-impl))
119 ;; see <http://www.franz.com/support/documentation/6.2/doc/pages/variables/compiler/s_cltl1-compile-file-toplevel-compatibility-p_s.htm>
120 (eval-when (:compile-toplevel :load-toplevel :execute)
121 (export ',name :swank-backend))
122 ',name)))
123
124 (defmacro defimplementation (name args &body body)
125 `(progn (defmethod ,name ,args ,@body)
126 (if (member ',name *interface-functions*)
127 (setq *unimplemented-interfaces*
128 (remove ',name *unimplemented-interfaces*))
129 (warn "DEFIMPLEMENTATION of undefined interface (~S)" ',name))
130 ',name))
131
132 (defun warn-unimplemented-interfaces ()
133 "Warn the user about unimplemented backend features.
134 The portable code calls this function at startup."
135 (warn "These Swank interfaces are unimplemented:~% ~A"
136 (sort (copy-list *unimplemented-interfaces*) #'string<)))
137
138
139 ;;;; Utilities
140
141 (defmacro with-struct ((conc-name &rest names) obj &body body)
142 "Like with-slots but works only for structs."
143 (flet ((reader (slot) (intern (concatenate 'string
144 (symbol-name conc-name)
145 (symbol-name slot))
146 (symbol-package conc-name))))
147 (let ((tmp (gensym "OO-")))
148 ` (let ((,tmp ,obj))
149 (symbol-macrolet
150 ,(loop for name in names collect
151 (typecase name
152 (symbol `(,name (,(reader name) ,tmp)))
153 (cons `(,(first name) (,(reader (second name)) ,tmp)))
154 (t (error "Malformed syntax in WITH-STRUCT: ~A" name))))
155 ,@body)))))
156
157
158 ;;;; TCP server
159
160 (definterface create-socket (host port)
161 "Create a listening TCP socket on interface HOST and port PORT .")
162
163 (definterface local-port (socket)
164 "Return the local port number of SOCKET.")
165
166 (definterface close-socket (socket)
167 "Close the socket SOCKET.")
168
169 (definterface accept-connection (socket)
170 "Accept a client connection on the listening socket SOCKET. Return
171 a stream for the new connection.")
172
173 (definterface add-sigio-handler (socket fn)
174 "Call FN whenever SOCKET is readable.")
175
176 (definterface remove-sigio-handlers (socket)
177 "Remove all sigio handlers for SOCKET.")
178
179 (definterface add-fd-handler (socket fn)
180 "Call FN when Lisp is waiting for input and SOCKET is readable.")
181
182 (definterface remove-fd-handlers (socket)
183 "Remove all fd-handlers for SOCKET.")
184
185 (definterface preferred-communication-style ()
186 "Return one of the symbols :spawn, :sigio, :fd-handler, or NIL."
187 nil)
188
189 ;;; Base condition for networking errors.
190 (define-condition network-error (simple-error) ())
191
192 (definterface emacs-connected (stream)
193 "Hook called when the first connection from Emacs is established.
194 Called from the INIT-FN of the socket server that accepts the
195 connection.
196
197 This is intended for setting up extra context, e.g. to discover
198 that the calling thread is the one that interacts with Emacs.
199
200 STREAM is the redirected user output stream to Emacs. This is passed
201 so that the backend can apply buffer flushing magic."
202 nil)
203
204
205 ;;;; Unix signals
206
207 (defconstant +sigint+ 2)
208
209 (definterface call-without-interrupts (fn)
210 "Call FN in a context where interrupts are disabled."
211 (funcall fn))
212
213 (definterface getpid ()
214 "Return the (Unix) process ID of this superior Lisp.")
215
216 (definterface lisp-implementation-type-name ()
217 "Return a short name for the Lisp implementation."
218 (lisp-implementation-type))
219
220 (definterface default-directory ()
221 "Return the default directory."
222 (directory-namestring (truename *default-pathname-defaults*)))
223
224 (definterface set-default-directory (directory)
225 "Set the default directory.
226 This is used to resolve filenames without directory component."
227 (setf *default-pathname-defaults* (truename (merge-pathnames directory)))
228 (default-directory))
229
230 (definterface call-with-syntax-hooks (fn)
231 "Call FN with hooks to handle special syntax."
232 (funcall fn))
233
234 (definterface default-readtable-alist ()
235 "Return a suitable initial value for SWANK:*READTABLE-ALIST*."
236 '())
237
238 (definterface quit-lisp ()
239 "Exit the current lisp image.")
240
241
242 ;;;; Compilation
243
244 (definterface call-with-compilation-hooks (func)
245 "Call FUNC with hooks to record compiler conditions.")
246
247 (defmacro with-compilation-hooks ((&rest ignore) &body body)
248 "Execute BODY as in CALL-WITH-COMPILATION-HOOKS."
249 (declare (ignore ignore))
250 `(call-with-compilation-hooks (lambda () (progn ,@body))))
251
252 (definterface swank-compile-string (string &key buffer position directory)
253 "Compile source from STRING. During compilation, compiler
254 conditions must be trapped and resignalled as COMPILER-CONDITIONs.
255
256 If supplied, BUFFER and POSITION specify the source location in Emacs.
257
258 Additionally, if POSITION is supplied, it must be added to source
259 positions reported in compiler conditions.
260
261 If DIRECTORY is specified it may be used by certain implementations to
262 rebind *DEFAULT-PATHNAME-DEFAULTS* which may improve the recording of
263 source information.")
264
265 (definterface operate-on-system (system-name operation-name &rest keyword-args)
266 "Perform OPERATION-NAME on SYSTEM-NAME using ASDF.
267 The KEYWORD-ARGS are passed on to the operation.
268 Example:
269 \(operate-on-system \"SWANK\" \"COMPILE-OP\" :force t)"
270 (unless (member :asdf *features*)
271 (error "ASDF is not loaded."))
272 (with-compilation-hooks ()
273 (let ((operate (find-symbol "OPERATE" :asdf))
274 (operation (find-symbol operation-name :asdf)))
275 (when (null operation)
276 (error "Couldn't find ASDF operation ~S" operation-name))
277 (apply operate operation system-name keyword-args))))
278
279 (definterface swank-compile-file (filename load-p)
280 "Compile FILENAME signalling COMPILE-CONDITIONs.
281 If LOAD-P is true, load the file after compilation.")
282
283 (deftype severity () '(member :error :warning :style-warning :note))
284
285 ;; Base condition type for compiler errors, warnings and notes.
286 (define-condition compiler-condition (condition)
287 ((original-condition
288 ;; The original condition thrown by the compiler if appropriate.
289 ;; May be NIL if a compiler does not report using conditions.
290 :type (or null condition)
291 :initarg :original-condition
292 :accessor original-condition)
293
294 (severity :type severity
295 :initarg :severity
296 :accessor severity)
297
298 (message :initarg :message
299 :accessor message)
300
301 (short-message :initarg :short-message
302 :initform nil
303 :accessor short-message)
304
305 (references :initarg :references
306 :initform nil
307 :accessor references)
308
309 (location :initarg :location
310 :accessor location)))
311
312
313 ;;;; Streams
314
315 (definterface make-fn-streams (input-fn output-fn)
316 "Return character input and output streams backended by functions.
317 When input is needed, INPUT-FN is called with no arguments to
318 return a string.
319 When output is ready, OUTPUT-FN is called with the output as its
320 argument.
321
322 Output should be forced to OUTPUT-FN before calling INPUT-FN.
323
324 The streams are returned as two values.")
325
326 (definterface make-stream-interactive (stream)
327 "Do any necessary setup to make STREAM work interactively.
328 This is called for each stream used for interaction with the user
329 \(e.g. *standard-output*). An implementation could setup some
330 implementation-specific functions to control output flushing at the
331 like."
332 nil)
333
334
335 ;;;; Documentation
336
337 (definterface arglist (name)
338 "Return the lambda list for the symbol NAME. NAME can also be
339 a lisp function object, on lisps which support this.
340
341 The result can be a list or the :not-available if the arglist
342 cannot be determined."
343 (declare (ignore name))
344 :not-available)
345
346 (definterface function-name (function)
347 "Return the name of the function object FUNCTION.
348
349 The result is either a symbol, a list, or NIL if no function name is available."
350 (declare (ignore function))
351 nil)
352
353 (definterface macroexpand-all (form)
354 "Recursively expand all macros in FORM.
355 Return the resulting form.")
356
357 (definterface describe-symbol-for-emacs (symbol)
358 "Return a property list describing SYMBOL.
359
360 The property list has an entry for each interesting aspect of the
361 symbol. The recognised keys are:
362
363 :VARIABLE :FUNCTION :SETF :TYPE :CLASS :MACRO :COMPILER-MACRO
364 :ALIEN-TYPE :ALIEN-STRUCT :ALIEN-UNION :ALIEN-ENUM
365
366 The value of each property is the corresponding documentation string,
367 or :NOT-DOCUMENTED. It is legal to include keys not listed here.
368
369 Properties should be included if and only if they are applicable to
370 the symbol. For example, only (and all) fbound symbols should include
371 the :FUNCTION property.
372
373 Example:
374 \(describe-symbol-for-emacs 'vector)
375 => (:CLASS :NOT-DOCUMENTED
376 :TYPE :NOT-DOCUMENTED
377 :FUNCTION \"Constructs a simple-vector from the given objects.\")")
378
379 (definterface describe-definition (name type)
380 "Describe the definition NAME of TYPE.
381 TYPE can be any value returned by DESCRIBE-SYMBOL-FOR-EMACS.
382
383 Return a documentation string, or NIL if none is available.")
384
385
386 ;;;; Debugging
387
388 (definterface call-with-debugging-environment (debugger-loop-fn)
389 "Call DEBUGGER-LOOP-FN in a suitable debugging environment.
390
391 This function is called recursively at each debug level to invoke the
392 debugger loop. The purpose is to setup any necessary environment for
393 other debugger callbacks that will be called within the debugger loop.
394
395 For example, this is a reasonable place to compute a backtrace, switch
396 to safe reader/printer settings, and so on.")
397
398 (define-condition sldb-condition (condition)
399 ((original-condition
400 :initarg :original-condition
401 :accessor original-condition))
402 (:report (lambda (condition stream)
403 (format stream "Condition in debugger code~@[: ~A~]"
404 (original-condition condition))))
405 (:documentation
406 "Wrapper for conditions that should not be debugged.
407
408 When a condition arises from the internals of the debugger, it is not
409 desirable to debug it -- we'd risk entering an endless loop trying to
410 debug the debugger! Instead, such conditions can be reported to the
411 user without (re)entering the debugger by wrapping them as
412 `sldb-condition's."))
413
414 (definterface compute-backtrace (start end)
415 "Return a list containing a backtrace of the condition current
416 being debugged. The results are unspecified if this function is
417 called outside the dynamic contour CALL-WITH-DEBUGGING-ENVIRONMENT.
418
419 START and END are zero-based indices constraining the number of frames
420 returned. Frame zero is defined as the frame which invoked the
421 debugger. If END is nil, return the frames from START to the end of
422 the stack.")
423
424 (definterface print-frame (frame stream)
425 "Print frame to stream.")
426
427 (definterface frame-source-location-for-emacs (frame-number)
428 "Return the source location for FRAME-NUMBER.")
429
430 (definterface frame-catch-tags (frame-number)
431 "Return a list of XXX list of what? catch tags for a debugger
432 stack frame. The results are undefined unless this is called
433 within the dynamic contour of a function defined by
434 DEFINE-DEBUGGER-HOOK.")
435
436 (definterface frame-locals (frame-number)
437 "Return a list of XXX local variable designators define me
438 for a debugger stack frame. The results are undefined unless
439 this is called within the dynamic contour of a function defined
440 by DEFINE-DEBUGGER-HOOK.")
441
442 (definterface frame-var-value (frame var)
443 "Return the value of VAR in FRAME.
444 FRAME is the number of the frame in the backtrace.
445 VAR is the number of the variable in the frame.")
446
447 (definterface disassemble-frame (frame-number)
448 "Disassemble the code for the FRAME-NUMBER.
449 The output should be written to standard output.
450 FRAME-NUMBER is a non-negative interger.")
451
452 (definterface eval-in-frame (form frame-number)
453 "Evaluate a Lisp form in the lexical context of a stack frame
454 in the debugger. The results are undefined unless called in the
455 dynamic contour of a function defined by DEFINE-DEBUGGER-HOOK.
456
457 FRAME-NUMBER must be a positive integer with 0 indicating the
458 frame which invoked the debugger.
459
460 The return value is the result of evaulating FORM in the
461 appropriate context.")
462
463 (definterface return-from-frame (frame-number form)
464 "Unwind the stack to the frame FRAME-NUMBER and return the value(s)
465 produced by evaluating FORM in the frame context to its caller.
466
467 Execute any clean-up code from unwind-protect forms above the frame
468 during unwinding.
469
470 Return a string describing the error if it's not possible to return
471 from the frame.")
472
473 (definterface restart-frame (frame-number)
474 "Restart execution of the frame FRAME-NUMBER with the same arguments
475 as it was called originally.")
476
477 (definterface format-sldb-condition (condition)
478 "Format a condition for display in SLDB."
479 (princ-to-string condition))
480
481 (definterface condition-references (condition)
482 "Return a list of documentation references for a condition.
483 Each reference is one of:
484 (:ANSI-CL
485 {:FUNCTION | :SPECIAL-OPERATOR | :MACRO | :SECTION | :GLOSSARY }
486 symbol-or-name)
487 (:SBCL :NODE node-name)"
488 '())
489
490 (definterface sldb-step (frame-number)
491 "Step to the next code location in the frame FRAME-NUMBER.")
492
493
494
495 ;;;; Definition finding
496
497 (defstruct (:location (:type list) :named
498 (:constructor make-location
499 (buffer position &optional hints)))
500 buffer position
501 ;; Hints is a property list optionally containing:
502 ;; :snippet SOURCE-TEXT
503 ;; This is a snippet of the actual source text at the start of
504 ;; the definition, which could be used in a text search.
505 hints)
506
507 (defstruct (:error (:type list) :named (:constructor)) message)
508 (defstruct (:file (:type list) :named (:constructor)) name)
509 (defstruct (:buffer (:type list) :named (:constructor)) name)
510 (defstruct (:position (:type list) :named (:constructor)) pos)
511
512 (definterface find-definitions (name)
513 "Return a list ((DSPEC LOCATION) ...) for NAME's definitions.
514
515 NAME is a \"definition specifier\".
516
517 DSPEC is a \"definition specifier\" describing the
518 definition, e.g., FOO or (METHOD FOO (STRING NUMBER)) or
519 \(DEFVAR FOO).
520
521 LOCATION is the source location for the definition.")
522
523 (definterface buffer-first-change (filename)
524 "Called for effect the first time FILENAME's buffer is modified."
525 nil)
526
527
528 ;;;; XREF
529
530 (definterface who-calls (function-name)
531 "Return the call sites of FUNCTION-NAME (a symbol).
532 The results is a list ((DSPEC LOCATION) ...).")
533
534 (definterface who-references (variable-name)
535 "Return the locations where VARIABLE-NAME (a symbol) is referenced.
536 See WHO-CALLS for a description of the return value.")
537
538 (definterface who-binds (variable-name)
539 "Return the locations where VARIABLE-NAME (a symbol) is bound.
540 See WHO-CALLS for a description of the return value.")
541
542 (definterface who-sets (variable-name)
543 "Return the locations where VARIABLE-NAME (a symbol) is set.
544 See WHO-CALLS for a description of the return value.")
545
546 (definterface who-macroexpands (macro-name)
547 "Return the locations where MACRO-NAME (a symbol) is expanded.
548 See WHO-CALLS for a description of the return value.")
549
550 (definterface who-specializes (class-name)
551 "Return the locations where CLASS-NAME (a symbol) is specialized.
552 See WHO-CALLS for a description of the return value.")
553
554 ;;; Simpler variants.
555
556 (definterface list-callers (function-name)
557 "List the callers of FUNCTION-NAME.
558 This function is like WHO-CALLS except that it is expected to use
559 lower-level means. Whereas WHO-CALLS is usually implemented with
560 special compiler support, LIST-CALLERS is usually implemented by
561 groveling for constants in function objects throughout the heap.
562
563 The return value is as for WHO-CALLS.")
564
565 (definterface list-callees (function-name)
566 "List the functions called by FUNCTION-NAME.
567 See LIST-CALLERS for a description of the return value.")
568
569
570 ;;;; Profiling
571
572 ;;; The following functions define a minimal profiling interface.
573
574 (definterface profile (fname)
575 "Marks symbol FNAME for profiling.")
576
577 (definterface profiled-functions ()
578 "Returns a list of profiled functions.")
579
580 (definterface unprofile (fname)
581 "Marks symbol FNAME as not profiled.")
582
583 (definterface unprofile-all ()
584 "Marks all currently profiled functions as not profiled."
585 (dolist (f (profiled-functions))
586 (unprofile f)))
587
588 (definterface profile-report ()
589 "Prints profile report.")
590
591 (definterface profile-reset ()
592 "Resets profile counters.")
593
594 (definterface profile-package (package callers-p methods)
595 "Wrap profiling code around all functions in PACKAGE. If a function
596 is already profiled, then unprofile and reprofile (useful to notice
597 function redefinition.)
598
599 If CALLERS-P is T names have counts of the most common calling
600 functions recorded.
601
602 When called with arguments :METHODS T, profile all methods of all
603 generic functions having names in the given package. Generic functions
604 themselves, that is, their dispatch functions, are left alone.")
605
606
607 ;;;; Inspector
608
609 (defclass inspector ()
610 ()
611 (:documentation "Super class of inspector objects.
612
613 Implementations should sub class in order to dispatch off of the
614 inspect-for-emacs method."))
615
616 (definterface make-default-inspector ()
617 "Return an inspector object suitable for passing to inspect-for-emacs.")
618
619 (definterface inspect-for-emacs (object inspector)
620 "Explain to emacs how to inspect OBJECT.
621
622 The argument INSPECTOR is an object representing how to get at
623 the internals of OBJECT, it is usually an implementation specific
624 class used simply for dispatching to the proper method.
625
626 The orgument INSPECTION-MODE is an object specifying how, and
627 what, to show to the user.
628
629 Returns two values: a string which will be used as the title of
630 the inspector buffer and a list specifying how to render the
631 object for inspection.
632
633 Every elementi of the list must be either a string, which will be
634 inserted into the buffer as is, or a list of the form:
635
636 (:value object &optional format) - Render an inspectable
637 object. If format is provided it must be a string and will be
638 rendered in place of the value, otherwise use princ-to-string.
639
640 (:newline) - Render a \\n
641
642 (:action label lambda) - Render LABEL (a text string) which when
643 clicked will call LAMBDA.
644
645 NIL - do nothing.")
646
647 (defmethod inspect-for-emacs (object inspector)
648 "Generic method for inspecting any kind of object.
649
650 Since we don't know how to deal with OBJECT we simply dump the
651 output of CL:DESCRIBE."
652 (declare (ignore inspector inspection-mode))
653 (values "A value."
654 `("Type: " (:value ,(type-of object))
655 (:newline)
656 "Don't know how to inspect the object, dumping output of CL:DESCIRBE:"
657 (:newline) (:newline)
658 ,(with-output-to-string (desc)
659 (describe object desc)))))
660
661 (definterface describe-primitive-type (object)
662 "Return a string describing the primitive type of object."
663 (declare (ignore object))
664 "N/A")
665
666
667 ;;;; Multithreading
668 ;;;
669 ;;; The default implementations are sufficient for non-multiprocessing
670 ;;; implementations.
671
672 (definterface startup-multiprocessing ()
673 "Initialize multiprocessing, if necessary.
674
675 This function is called directly through the listener, not in an RPC
676 from Emacs. This is to support interfaces such as CMUCL's
677 MP::STARTUP-IDLE-AND-TOP-LEVEL-LOOPS which does not return like a
678 normal function."
679 nil)
680
681 (definterface spawn (fn &key name)
682 "Create a new thread to call FN.")
683
684 (definterface thread-id (thread)
685 "Return an Emacs-parsable object to identify THREAD.
686
687 Ids should be comparable with equal, i.e.:
688 (equal (thread-id <t1>) (thread-id <t2>)) <==> (eq <t1> <t2>)")
689
690 (definterface find-thread (id)
691 "Return the thread for ID.
692 ID should be an id previously obtained with THREAD-ID.
693 Can return nil if the thread no longer exists.")
694
695 (definterface thread-name (thread)
696 "Return the name of THREAD.
697
698 Thread names are be single-line strings and are meaningful to the
699 user. They do not have to be unique."
700 (declare (ignore thread))
701 "The One True Thread")
702
703 (definterface thread-status (thread)
704 "Return a string describing THREAD's state."
705 (declare (ignore thread))
706 "")
707
708 (definterface make-lock (&key name)
709 "Make a lock for thread synchronization.
710 Only one thread may hold the lock (via CALL-WITH-LOCK-HELD) at a time."
711 (declare (ignore name))
712 :null-lock)
713
714 (definterface call-with-lock-held (lock function)
715 "Call FUNCTION with LOCK held, queueing if necessary."
716 (declare (ignore lock)
717 (type function function))
718 (funcall function))
719
720 (definterface current-thread ()
721 "Return the currently executing thread."
722 0)
723
724 (definterface all-threads ()
725 "Return a list of all threads.")
726
727 (definterface thread-alive-p (thread)
728 "Test if THREAD is termintated."
729 (member thread (all-threads)))
730
731 (definterface interrupt-thread (thread fn)
732 "Cause THREAD to execute FN.")
733
734 (definterface kill-thread (thread)
735 "Kill THREAD."
736 (declare (ignore thread))
737 nil)
738
739 (definterface send (thread object)
740 "Send OBJECT to thread THREAD.")
741
742 (definterface receive ()
743 "Return the next message from current thread's mailbox.")

  ViewVC Help
Powered by ViewVC 1.1.5