GDB (API)
|
00001 # ipc.tcl 00002 # Copyright (C) 2004 Red Hat, Inc. 00003 # 00004 # This program is free software; you can redistribute it and/or modify it 00005 # under the terms of the GNU General Public License (GPL) as published by 00006 # the Free Software Foundation; either version 2 of the License, or (at 00007 # your option) any later version. 00008 # 00009 # This program is distributed in the hope that it will be useful, 00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 # GNU General Public License for more details. 00013 00014 # ---------------------------------------------------------------------- 00015 # Implements IPC for multiple Insight instances, allowing any Insight 00016 # to send commands to all other Insights on the same host. 00017 # 00018 # PUBLIC METHODS: 00019 # 00020 # send $cmd - sends $cmd to all Insights 00021 # 00022 # ---------------------------------------------------------------------- 00023 00024 itcl::class Iipc { 00025 00026 private variable socklist 00027 private variable portnum 9909 00028 private variable serversock 00029 00030 constructor {} { 00031 init 00032 } 00033 00034 destructor { 00035 debug 00036 foreach sock $socklist { 00037 catch {::close $sock} 00038 } 00039 00040 if {$serversock != "0"} { 00041 catch {::close $serversock} 00042 } 00043 set ::iipc 0 00044 } 00045 00046 private method init {} { 00047 debug "iipc init" 00048 set socklist {} 00049 set serversock 0 00050 set portnum [pref get gdb/ipc/port] 00051 if {[catch {socket -server [code $this accept] $portnum} serversock]} { 00052 debug "server already exists. Connecting to it." 00053 set socklist [socket localhost $portnum] 00054 fconfigure $socklist -buffering line -blocking 0 00055 fileevent $socklist readable [code $this read $socklist] 00056 } 00057 set ::iipc 1 00058 } 00059 00060 # accept new connection to server 00061 private method accept {sock addr port} { 00062 debug "accepting connecting from $sock -> $addr:$port" 00063 fconfigure $sock -buffering line -blocking 0 00064 lappend socklist $sock 00065 fileevent $sock readable [code $this sread $sock] 00066 } 00067 00068 private method read {s} { 00069 if [eof $s] { 00070 debug "The server died on $s!!" 00071 catch {::close $s} 00072 init 00073 return 00074 } 00075 gets $s res 00076 debug "Server: $res" 00077 switch $res { 00078 quit { gdb_force_quit } 00079 stop { gdbtk_stop } 00080 run { gdbtk_run } 00081 default { 00082 catch {gdb_immediate "$res"} 00083 } 00084 } 00085 } 00086 00087 # server read method. Reads data then forwards 00088 # it to all listening sockets. 00089 private method sread {s} { 00090 if [eof $s] { 00091 close $s 00092 return 00093 } 00094 gets $s res 00095 if {$res != ""} { 00096 debug "Got: $res" 00097 foreach sock $socklist { 00098 if {$s != $sock} { 00099 if {[catch {puts $sock $res}]} { 00100 close $sock 00101 } 00102 } 00103 } 00104 switch $res { 00105 quit { gdb_force_quit } 00106 stop { gdbtk_stop } 00107 run { gdbtk_run } 00108 default { 00109 catch {gdb_immediate "$res"} 00110 } 00111 } 00112 } 00113 } 00114 00115 # send data to all sockets. 00116 public method send {cmd} { 00117 debug "send $cmd" 00118 foreach sock $socklist { 00119 if {[catch {puts $sock $cmd}]} { 00120 close $sock 00121 } 00122 } 00123 } 00124 00125 private method close {s} { 00126 debug "closing socket $s" 00127 set socklist [lremove $socklist $s] 00128 catch {::close $s} 00129 } 00130 } 00131 00132 00133 00134 00135