Changeset 24 for chess


Ignore:
Timestamp:
02/05/09 21:05:43 (13 years ago)
Author:
BegemoT
Message:

threading issues

Location:
chess
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • chess/chess.jad

    r23 r24  
    11MIDlet-1: Chess Game, , chess.ui.ChessMIDlet 
    2 MIDlet-Jar-Size: 309643 
     2MIDlet-Jar-Size: 84507 
    33MIDlet-Jar-URL: chess.jar 
    4 MIDlet-Name: chess 
     4MIDlet-Name: Chess 
    55MIDlet-Vendor: I am 
    6 MIDlet-Version: 1.0 
     6MIDlet-Version: 1.1.2 
    77MicroEdition-Configuration: CLDC-1.0 
    88MicroEdition-Profile: MIDP-2.0 
  • chess/src/chess/remote/impl/BTRemote.java

    r23 r24  
    22 
    33import java.io.IOException; 
     4import java.io.InterruptedIOException; 
    45import java.util.*; 
    56import javax.bluetooth.*; 
     
    1920 */ 
    2021public class BTRemote implements IRemote { 
    21     public static final String BTSPP_SCHEME = "btspp://"; 
    22     public static final String MY_SERVICE_NUMBER = "3B9FA89520078C303355AAA694238F08;name=ChessGameServer"; 
    23  
    24     public static final IRemoteNode[] EMPTY = new IRemoteNode[0]; 
    25  
    26     private final LocalDevice localDevice; 
    27     private final Vector devices = new Vector(); 
    28  
    29     public BTRemote() throws Exception { 
    30         localDevice = LocalDevice.getLocalDevice(); 
    31         fillupCache(); 
    32     } 
    33  
    34     private synchronized void fillupCache() { 
    35         final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 
    36         final RemoteDevice[] preknownDevices = agent.retrieveDevices( DiscoveryAgent.PREKNOWN ); 
    37         if ( preknownDevices != null ) { 
    38             for ( int i = 0; i < preknownDevices.length; i++ ) { 
    39                 final RemoteDevice device = preknownDevices[i]; 
    40                 devices.addElement( device ); 
    41             } 
    42         } 
    43         final RemoteDevice[] cachedDevices = agent.retrieveDevices( DiscoveryAgent.CACHED ); 
    44         if ( cachedDevices != null ) { 
    45             for ( int i = 0; i < cachedDevices.length; i++ ) { 
    46                 final RemoteDevice device = cachedDevices[i]; 
    47                 devices.addElement( device ); 
    48             } 
    49         } 
    50     } 
    51  
    52     private synchronized void refreshCache() { 
    53         devices.removeAllElements(); 
    54         fillupCache(); 
    55     } 
    56  
    57     public IAsyncProcess waitForIncoming( final IServerListener l ) { 
    58         return new WaitForIncomingThread( localDevice, l ); 
    59     } 
    60  
    61     public IAsyncProcess getAvailable( final boolean refresh, 
    62                                        final IClientListener l ) { 
    63         if ( refresh ) { 
    64             try { 
    65                 final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 
    66                 return new QueryDeviceProcess( this, agent, l ); 
    67             } catch ( Exception e ) { 
    68                 e.printStackTrace(); 
    69                 l.finished( null ); 
    70                 return null; 
    71             } 
    72         } else { 
    73             final IRemoteNode[] nodes = getNodes(); 
    74             l.finished( nodes ); 
    75             return null; 
    76         } 
    77     } 
    78  
    79     private synchronized IRemoteNode[] getNodes() { 
    80         if ( devices.isEmpty() ) { 
    81             return EMPTY; 
    82         } 
    83         final int length = devices.size(); 
    84         final IRemoteNode[] nodes = new IRemoteNode[length]; 
    85         for ( int i = 0; i < length; i++ ) { 
    86             try { 
    87                 final RemoteDevice device = ( RemoteDevice )devices.elementAt( i ); 
    88                 final BTNode node = new BTNode( device ); 
    89                 nodes[i] = node; 
    90             } catch ( IOException e ) { 
    91                 e.printStackTrace(); 
    92             } 
    93         } 
    94         return nodes; 
    95     } 
    96  
    97     private static class WaitForIncomingThread extends BaseAsyncProcess { 
    98         private final LocalDevice localDevice; 
    99  
    100         public WaitForIncomingThread( final LocalDevice local, 
    101                                       final IServerListener listener ) { 
    102             super( listener ); 
    103             this.localDevice = local; 
    104             start(); 
    105         } 
    106  
    107         public void run() { 
    108             try { 
    109                 localDevice.setDiscoverable( DiscoveryAgent.GIAC ); 
    110                 setStatus( IN_PROCESS ); 
    111                 while ( true ) { 
    112                     try { 
    113                         final StreamConnectionNotifier server = ( StreamConnectionNotifier )Connector.open( 
    114                                 BTSPP_SCHEME +"localhost:" + MY_SERVICE_NUMBER, 
    115                                 Connector.READ_WRITE, 
    116                                 true 
    117                         ); 
    118                         Util.log.println( "creating server and waiting for incoming" ); 
    119                         try { 
    120                             while ( true ) { 
    121                                 // Îæèäàåì âõîäÿùåå ïîòîêîâîå ñîåäèíåíèå 
    122                                 final StreamConnection conn = server.acceptAndOpen(); 
    123                                 Util.log.println( "accepted incoming:" + conn ); 
    124                                 final BTNode client = new BTNode( conn ); 
    125                                 if ( listener.incoming( client ) ) { 
    126                                     //åñëè êëèåíò ïðèíÿò -- âûõîäèì (èãðà äîïóñêàåò òîëüêî îäíîãî ñîïåðíèêà) 
    127                                     Util.log.println( "client accepted -> close server" ); 
    128                                     setStatus( SUCCEEDED ); 
    129                                     return; 
    130                                 } 
    131                                 client.close(); 
    132                             } 
    133                         } catch ( IOException ex ) { 
    134                             ex.printStackTrace(); 
    135                         } finally { 
    136                             try { 
    137                                 server.close(); 
    138                             } catch ( IOException e ) { 
    139                                 e.printStackTrace(); 
    140                             } 
    141                         } 
    142                     } catch ( IOException ex ) { 
    143                         ex.printStackTrace(); 
    144                         setStatus( FAILED ); 
    145                         return; 
    146                     } 
    147                 } 
    148             } catch ( IOException ex ) { 
    149                 ex.printStackTrace(); 
    150                 setStatus( FAILED ); 
    151             } finally { 
    152                 listener.finished( null ); 
    153                 Util.log.println( "server stopped" ); 
    154             } 
    155         } 
    156     } 
    157  
    158     private static class QueryDeviceProcess implements IAsyncProcess, DiscoveryListener { 
    159         private final DiscoveryAgent agent; 
    160         private final IClientListener l; 
    161         private final BTRemote remote; 
    162  
    163         private volatile int status = IN_PROCESS; 
    164  
    165         public QueryDeviceProcess( final BTRemote remote, 
    166                                    final DiscoveryAgent agent, 
    167                                    final IClientListener l ) throws Exception { 
    168             this.remote = remote; 
    169             this.agent = agent; 
    170             this.l = l; 
    171             agent.startInquiry( DiscoveryAgent.GIAC, this ); 
    172         } 
    173  
    174         public int status() { 
    175             return status; 
    176         } 
    177  
    178         public void interrupt( final boolean waitFor ) { 
    179             agent.cancelInquiry( this ); 
    180         } 
    181  
    182         public IAsyncProcessListener getListener() { 
    183             return l; 
    184         } 
    185  
    186         public void deviceDiscovered( final RemoteDevice btDevice, 
    187                                       final DeviceClass cod ) { 
    188             Util.log.println( "device found:" + btDevice.getBluetoothAddress() ); 
    189         } 
    190  
    191         public void servicesDiscovered( final int transID, 
    192                                         final ServiceRecord[] servRecord ) { 
    193             Util.log.println( "service found:" + transID ); 
    194         } 
    195  
    196         public void serviceSearchCompleted( final int transID, 
    197                                             final int respCode ) { 
    198  
    199         } 
    200  
    201         public void inquiryCompleted( final int discType ) { 
    202             if ( discType == INQUIRY_COMPLETED ) { 
    203                 remote.refreshCache(); 
    204                 status = SUCCEEDED; 
    205                 l.finished( remote.getNodes() ); 
    206             } else { 
    207                 status = FAILED; 
    208                 l.finished( null ); 
    209             } 
    210         } 
    211     } 
     22        public static final String BTSPP_SCHEME = "btspp://"; 
     23        public static final String MY_SERVICE_NUMBER = "3B9FA89520078C303355AAA694238F08;name=ChessGameServer"; 
     24 
     25        public static final IRemoteNode[] EMPTY = new IRemoteNode[0]; 
     26 
     27        private final LocalDevice localDevice; 
     28        private final Vector devices = new Vector(); 
     29 
     30        public BTRemote() throws Exception { 
     31                localDevice = LocalDevice.getLocalDevice(); 
     32                fillupCache(); 
     33        } 
     34 
     35        private synchronized void fillupCache() { 
     36                final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 
     37                final RemoteDevice[] preknownDevices = agent.retrieveDevices( DiscoveryAgent.PREKNOWN ); 
     38                if( preknownDevices != null ) { 
     39                        for( int i = 0; i < preknownDevices.length; i++ ) { 
     40                                final RemoteDevice device = preknownDevices[i]; 
     41                                devices.addElement( device ); 
     42                        } 
     43                } 
     44                final RemoteDevice[] cachedDevices = agent.retrieveDevices( DiscoveryAgent.CACHED ); 
     45                if( cachedDevices != null ) { 
     46                        for( int i = 0; i < cachedDevices.length; i++ ) { 
     47                                final RemoteDevice device = cachedDevices[i]; 
     48                                devices.addElement( device ); 
     49                        } 
     50                } 
     51        } 
     52 
     53        private synchronized void refreshCache() { 
     54                devices.removeAllElements(); 
     55                fillupCache(); 
     56        } 
     57 
     58        public IAsyncProcess waitForIncoming( final IServerListener l ) { 
     59                return new WaitForIncomingThread( localDevice, l ); 
     60        } 
     61 
     62        public IAsyncProcess getAvailable( final boolean refresh, 
     63                                           final IClientListener l ) { 
     64                if( refresh ) { 
     65                        try { 
     66                                final DiscoveryAgent agent = localDevice.getDiscoveryAgent(); 
     67                                return new QueryDeviceProcess( this, agent, l ); 
     68                        } catch( Exception e ) { 
     69                                e.printStackTrace(); 
     70                                l.finished( null ); 
     71                                return null; 
     72                        } 
     73                } else { 
     74                        final IRemoteNode[] nodes = getNodes(); 
     75                        l.finished( nodes ); 
     76                        return null; 
     77                } 
     78        } 
     79 
     80        private synchronized IRemoteNode[] getNodes() { 
     81                if( devices.isEmpty() ) { 
     82                        return EMPTY; 
     83                } 
     84                final int length = devices.size(); 
     85                final IRemoteNode[] nodes = new IRemoteNode[length]; 
     86                for( int i = 0; i < length; i++ ) { 
     87                        try { 
     88                                final RemoteDevice device = ( RemoteDevice ) devices.elementAt( i ); 
     89                                final BTNode node = new BTNode( device ); 
     90                                nodes[i] = node; 
     91                        } catch( IOException e ) { 
     92                                e.printStackTrace(); 
     93                        } 
     94                } 
     95                return nodes; 
     96        } 
     97 
     98        private static class WaitForIncomingThread extends BaseAsyncProcess { 
     99                private final LocalDevice localDevice; 
     100                private StreamConnectionNotifier server; 
     101 
     102                public WaitForIncomingThread( final LocalDevice local, 
     103                                              final IServerListener listener ) { 
     104                        super( listener ); 
     105                        this.localDevice = local; 
     106                        start(); 
     107                } 
     108 
     109                public void run() { 
     110                        try { 
     111                                localDevice.setDiscoverable( DiscoveryAgent.GIAC ); 
     112                                setStatus( IN_PROCESS ); 
     113                                while( true ) { 
     114                                        server = ( StreamConnectionNotifier ) Connector.open( 
     115                                                        BTSPP_SCHEME + "localhost:" + MY_SERVICE_NUMBER, 
     116                                                        Connector.READ_WRITE, 
     117                                                        true 
     118                                        ); 
     119                                        Util.log.println( "creating server and waiting for incoming" ); 
     120                                        try { 
     121                                                while( true ) { 
     122                                                        // Îæèäàåì âõîäÿùåå ïîòîêîâîå ñîåäèíåíèå 
     123                                                        final StreamConnection conn = server.acceptAndOpen(); 
     124                                                        Util.log.println( "accepted incoming:" + conn ); 
     125                                                        final BTNode client = new BTNode( conn ); 
     126                                                        if( listener.incoming( client ) ) { 
     127                                                                //åñëè êëèåíò ïðèíÿò -- âûõîäèì (èãðà äîïóñêàåò òîëüêî îäíîãî ñîïåðíèêà) 
     128                                                                Util.log.println( "client accepted -> close server" ); 
     129                                                                setStatus( SUCCEEDED ); 
     130                                                                return; 
     131                                                        } 
     132                                                        client.close(); 
     133                                                } 
     134                                        } catch( InterruptedIOException ex ) { 
     135                                                Util.log.println( "server was closed:" + ex.getMessage() ); 
     136                                                return; 
     137                                        } catch( IOException ex ) { 
     138                                                Util.log.println( "server got error -- trying to recreate server connection" ); 
     139                                                ex.printStackTrace(); 
     140                                        } finally { 
     141                                                if( server != null ) { 
     142                                                        try { 
     143                                                                server.close(); 
     144                                                                server = null; 
     145                                                        } catch( IOException e ) { 
     146                                                                e.printStackTrace(); 
     147                                                        } 
     148                                                } 
     149                                        } 
     150 
     151                                } 
     152                        } catch( IOException ex ) { 
     153                                //åñëè íå óäàëîñü îòêðûòü ñîåäèíåíèå -- ýòî ïèçäåö. óõîäèì 
     154                                //...íå óäàëîñü îïóáëèêîâàòü óñòðîéñòâî -- ïèçäåö, óõîäèì 
     155                                ex.printStackTrace(); 
     156                                setStatus( FAILED ); 
     157                        } finally { 
     158                                listener.finished( null ); 
     159                                Util.log.println( "server stopped" ); 
     160                        } 
     161                } 
     162 
     163 
     164                public void interrupt( final boolean waitFor ) { 
     165                        if( isAlive() ) { 
     166//                              interrupt(); 
     167                                if( server != null ) { 
     168                                        try { 
     169                                                server.close(); 
     170                                                server = null; 
     171                                        } catch( IOException e ) { 
     172                                                e.printStackTrace(); 
     173                                        } 
     174                                } 
     175                                if( waitFor && Thread.currentThread() != this ) { 
     176                                        try { 
     177                                                join(); 
     178                                        } catch( InterruptedException e ) { 
     179                                                e.printStackTrace(); 
     180                                        } 
     181                                } 
     182                        } 
     183                } 
     184        } 
     185 
     186        private static class QueryDeviceProcess implements IAsyncProcess, DiscoveryListener { 
     187                private final DiscoveryAgent agent; 
     188                private final IClientListener l; 
     189                private final BTRemote remote; 
     190 
     191                private volatile int status = IN_PROCESS; 
     192 
     193                public QueryDeviceProcess( final BTRemote remote, 
     194                                           final DiscoveryAgent agent, 
     195                                           final IClientListener l ) throws Exception { 
     196                        this.remote = remote; 
     197                        this.agent = agent; 
     198                        this.l = l; 
     199                        agent.startInquiry( DiscoveryAgent.GIAC, this ); 
     200                } 
     201 
     202                public int status() { 
     203                        return status; 
     204                } 
     205 
     206                public void interrupt( final boolean waitFor ) { 
     207                        agent.cancelInquiry( this ); 
     208                } 
     209 
     210                public IAsyncProcessListener getListener() { 
     211                        return l; 
     212                } 
     213 
     214                public void deviceDiscovered( final RemoteDevice btDevice, 
     215                                              final DeviceClass cod ) { 
     216                        Util.log.println( "device found:" + btDevice.getBluetoothAddress() ); 
     217                } 
     218 
     219                public void servicesDiscovered( final int transID, 
     220                                                final ServiceRecord[] servRecord ) { 
     221                        Util.log.println( "service found:" + transID ); 
     222                } 
     223 
     224                public void serviceSearchCompleted( final int transID, 
     225                                                    final int respCode ) { 
     226 
     227                } 
     228 
     229                public void inquiryCompleted( final int discType ) { 
     230                        if( discType == INQUIRY_COMPLETED ) { 
     231                                remote.refreshCache(); 
     232                                status = SUCCEEDED; 
     233                                l.finished( remote.getNodes() ); 
     234                        } else { 
     235                                status = FAILED; 
     236                                l.finished( null ); 
     237                        } 
     238                } 
     239        } 
    212240} 
Note: See TracChangeset for help on using the changeset viewer.