module: access-path-implementation synopsis: Implementation of the class author: Paul Howard Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /* THREADING ISSUES: There are non-trivial thread issues associated with the access-path implementation. There is a restriction under Windows that debug events can only be listened for on the thread that started up the application. This means we may - in time - need some slightly convoluted locking mechanism to satisfy this implied serialization constraint. For now, I've ignored all this! */ define constant $empty-string = ""; ///// define abstract class () slot connection :: ; slot access-path-abstract-handle :: , init-value: #f; slot libraries :: , init-function: method () make (, size: 0) end method; slot threads :: , init-function: method () make (, size: 0) end method; slot register-set :: , init-value: #[]; slot cached-exception-set :: , init-value: #[]; slot cached-receivable-first-chance-exceptions? :: , init-value: #f; slot first-chance-exception-set :: , init-function: method () make (, size: 0); end method; slot state :: , init-value: #"unstarted"; end class; define class () slot access-path-application :: , required-init-keyword: application:; slot access-path-arguments :: , init-keyword: arguments:, init-value: $empty-string; end class; // access-path-application should return #f for other "breeds" of access-path define method access-path-application (ap :: ) #f; end method; define class () slot access-path-process :: , required-init-keyword: process:; inherited slot state :: , init-value: #"running"; end class; // access-path-process should return #f for other "breeds" of access path define method access-path-process (ap :: ) #f; end method; define class () slot access-path-core-file :: , required-init-keyword: core-file:; inherited slot state :: , init-value: #"post-mortem"; end class; // access-path-core-file should return #f for other "breeds" of access path define method access-path-core-file (ap :: ) #f; end method; define method make (class == , #rest keys, #key application = #f, arguments = #f, process = #f, core-file = #f, #all-keys) // Create the appropriate instance. if (application) apply (make, , keys); elseif (process) apply (make, , keys); elseif (core-file) apply (make, , keys); else // This is not a legal call to make on error("Pardon me, but you've not supplied required keyword args."); end if; end method; define method initialize (ap :: , #key) => () next-method(); // Create the connection to the debugger. // HACK: *default-local-debugger-connection* is used, though we really // should be passing the server as an argument to make on // let debug-connection = make (, machine: *default-local-debugger-connection*); // Fire up the application as a side-effect of making the access path. // The debugger nub will be spawned, and will start the application in // a "frozen" state. Clients must call restart() on the returned // instance to get things moving... start-application-on-connection (debug-connection, as (, ap.access-path-application), ap.access-path-arguments); // Finally, save the generated access connection in the access path // instance for future communications. ap.connection := debug-connection; end method; define method initialize (ap :: , #key) => () next-method(); end method; define method initialize (ap :: , #key) => () next-method(); end method;