| @@ -53,6 +53,10 @@ rename_client = libjack.jack_rename_client | |||||
| rename_client.argtypes = [ client_p, c_char_p, c_char_p ] | rename_client.argtypes = [ client_p, c_char_p, c_char_p ] | ||||
| rename_client.restype = c_int | rename_client.restype = c_int | ||||
| reserve_client_name = libjack.jack_reserve_client_name | |||||
| reserve_client_name.argtypes = [ client_p, c_char_p, c_char_p ] | |||||
| reserve_client_name.restype = c_int | |||||
| class jack_session_command_t( Structure ): | class jack_session_command_t( Structure ): | ||||
| _fields_ = [ ("uuid", 16*c_char ), ("clientname", 33*c_char), ("command", 256*c_char ) ] | _fields_ = [ ("uuid", 16*c_char ), ("clientname", 33*c_char), ("command", 256*c_char ) ] | ||||
| @@ -163,6 +167,7 @@ class Client( object ): | |||||
| self.ports = [] | self.ports = [] | ||||
| self.commandline = None | self.commandline = None | ||||
| self.isinfra = False | self.isinfra = False | ||||
| self.uuid = None | |||||
| def get_commandline( self ): | def get_commandline( self ): | ||||
| if self.commandline: | if self.commandline: | ||||
| @@ -173,6 +178,12 @@ class Client( object ): | |||||
| def set_commandline( self, cmdline ): | def set_commandline( self, cmdline ): | ||||
| self.commandline = cmdline | self.commandline = cmdline | ||||
| def get_uuid( self ): | |||||
| return self.uuid | |||||
| def set_uuid( self, uuid ): | |||||
| self.uuid = uuid | |||||
| def add_port( self, portname ): | def add_port( self, portname ): | ||||
| self.ports.append( Port( self.client, portname ) ) | self.ports.append( Port( self.client, portname ) ) | ||||
| @@ -199,6 +210,7 @@ class JackGraph( object ): | |||||
| def __init__( self, client, ports, uuids=[] ): | def __init__( self, client, ports, uuids=[] ): | ||||
| self.client = client | self.client = client | ||||
| self.clients = {} | self.clients = {} | ||||
| self.reserved_names = [] | |||||
| i=0 | i=0 | ||||
| while(ports[i]): | while(ports[i]): | ||||
| @@ -226,23 +238,23 @@ class JackGraph( object ): | |||||
| return | return | ||||
| oldname = client.name | oldname = client.name | ||||
| cname_split = client.name.split('-') | |||||
| newname = self.get_free_name( client.name ) | |||||
| client.rename( newname ) | |||||
| del self.clients[oldname] | |||||
| self.clients[newname] = client | |||||
| def get_free_name( self, oldname, other_names=[] ): | |||||
| cname_split = oldname.split('-') | |||||
| if len(cname_split) == 1: | if len(cname_split) == 1: | ||||
| cname_prefix = cname_split[0] | cname_prefix = cname_split[0] | ||||
| else: | else: | ||||
| cname_prefix = string.join( cname_split[:-1], '-' ) | cname_prefix = string.join( cname_split[:-1], '-' ) | ||||
| num = 1 | num = 1 | ||||
| while ("%s-%d"%(cname_prefix,num)) in (self.clients.keys()+self.reserved_names): | |||||
| while ("%s-%d"%(cname_prefix,num)) in (self.clients.keys()+self.reserved_names+other_names): | |||||
| num+=1 | num+=1 | ||||
| # XXX: this might still fail due to race. | |||||
| # also needs to lock | |||||
| newname = "%s-%d"%(cname_prefix,num ) | |||||
| client.rename( newname ) | |||||
| del self.clients[oldname] | |||||
| self.clients[newname] = client | |||||
| def remove_client( self, name ): | def remove_client( self, name ): | ||||
| @@ -261,6 +273,14 @@ class JackGraph( object ): | |||||
| for c in self.clients.values(): | for c in self.clients.values(): | ||||
| self.check_client_name( c ) | self.check_client_name( c ) | ||||
| def get_taken_names( self ): | |||||
| return self.clients.keys() + self.reserved_names | |||||
| def reserve_name( self, uuid, name ): | |||||
| if reserve_client_name( self.client, name, uuid ): | |||||
| raise Exception( "reservation failure" ) | |||||
| self.reserved_names.append( name ) | |||||
| class NotifyReply(object): | class NotifyReply(object): | ||||
| def __init__( self, uuid, clientname, commandline ): | def __init__( self, uuid, clientname, commandline ): | ||||
| @@ -59,12 +59,21 @@ class SessionManager( object ): | |||||
| print sd.get_client_names() | print sd.get_client_names() | ||||
| g.ensure_clientnames( sd.get_reg_client_names() ) | |||||
| if opt.renames: | |||||
| g.ensure_clientnames( sd.get_reg_client_names() ) | |||||
| # get graph again... renaming isnt prefect yet. | |||||
| g=self.cl.get_graph() | |||||
| # get graph again... renaming isnt prefect yet. | |||||
| g=self.cl.get_graph() | |||||
| # build up list of port connections | |||||
| # fixup names, doing this unconditionally, because | |||||
| # a client rename might have failed. | |||||
| sd.fixup_client_names( g ) | |||||
| # now we have mangled all the names, lets reserve them. | |||||
| for (uuid, clientname) in sd.get_uuid_client_pairs(): | |||||
| print "reserving name %s"%clientname | |||||
| g.reserve_name( uuid, clientname ) | |||||
| # build up list of port connections | |||||
| conns = [] | conns = [] | ||||
| for p in sd.get_port_names(): | for p in sd.get_port_names(): | ||||
| for c in sd.get_connections_for_port( p ): | for c in sd.get_connections_for_port( p ): | ||||
| @@ -113,7 +122,7 @@ class SessionManager( object ): | |||||
| def save_session( self, name ): | def save_session( self, name ): | ||||
| if os.path.exists( self.sessiondir+name ): | if os.path.exists( self.sessiondir+name ): | ||||
| print "session %s already exists" | |||||
| print "session %s already exists"%name | |||||
| return -1 | return -1 | ||||
| os.mkdir( self.sessiondir+name ) | os.mkdir( self.sessiondir+name ) | ||||
| g=self.cl.get_graph() | g=self.cl.get_graph() | ||||
| @@ -122,6 +131,7 @@ class SessionManager( object ): | |||||
| for n in notify: | for n in notify: | ||||
| c = g.get_client( n.clientname ) | c = g.get_client( n.clientname ) | ||||
| c.set_commandline( n.commandline ) | c.set_commandline( n.commandline ) | ||||
| c.set_uuid( n.uuid ) | |||||
| sd = state.SessionDom() | sd = state.SessionDom() | ||||
| @@ -196,6 +206,8 @@ oparser.add_option( "--quitdaemon", action="store_true", dest="quitdaemon", defa | |||||
| # help="SaveAs And Quit" ) | # help="SaveAs And Quit" ) | ||||
| oparser.add_option( "--load", action="store", dest="load", type="string", | oparser.add_option( "--load", action="store", dest="load", type="string", | ||||
| help="Load Session with <name>" ) | help="Load Session with <name>" ) | ||||
| oparser.add_option( "--renames", action="store_true", dest="renames", default=False, | |||||
| help="Allow renaming offending clients" ) | |||||
| (opt,args) = oparser.parse_args() | (opt,args) = oparser.parse_args() | ||||
| @@ -14,6 +14,8 @@ class SessionDom( object ): | |||||
| cl_elem = Element( "jackclient" ) | cl_elem = Element( "jackclient" ) | ||||
| cl_elem.setAttribute( "cmdline", client.get_commandline() ) | cl_elem.setAttribute( "cmdline", client.get_commandline() ) | ||||
| cl_elem.setAttribute( "jackname", client.name ) | cl_elem.setAttribute( "jackname", client.name ) | ||||
| if client.get_uuid(): | |||||
| cl_elem.setAttribute( "uuid", client.get_uuid() ) | |||||
| if client.isinfra: | if client.isinfra: | ||||
| cl_elem.setAttribute( "infra", "True" ) | cl_elem.setAttribute( "infra", "True" ) | ||||
| else: | else: | ||||
| @@ -84,6 +86,23 @@ class SessionDom( object ): | |||||
| if c.getAttribute( "jackname" ) == name: | if c.getAttribute( "jackname" ) == name: | ||||
| return c.getAttribute( "cmdline" ) | return c.getAttribute( "cmdline" ) | ||||
| def get_uuid_client_pairs( self ): | |||||
| retval = [] | |||||
| doc = self.dom.documentElement | |||||
| for c in doc.getElementsByTagName( "jackclient" ): | |||||
| if c.getAttribute( "infra" ) != "True": | |||||
| retval.append( (c.getAttribute( "uuid" ), c.getAttribute( "jackname" )) ) | |||||
| return retval | |||||
| def fixup_client_names( self, graph ): | |||||
| doc = self.dom.documentElement | |||||
| for c in doc.getElementsByTagName( "jackclient" ): | |||||
| cname = c.getAttribute( "jackname" ) | |||||
| if cname in graph.get_taken_names(): | |||||
| c.setAttribute( "jackname", graph.get_free_name( cname, self.get_reg_client_names() ) ) | |||||