[guardian-dev] Fwd: libaccesspoint concurrency help

Nathan of Guardian nathan at guardianproject.info
Tue May 12 11:00:51 EDT 2015


and the diff:

diff --git
a/libaccesspoint/src/main/java/cc/mvdan/libaccesspoint/WifiApControl.java
b/libaccesspoint/src/main/java/cc/mvdan/libaccesspoint/WifiApControl.java
index ca3c0fe..95d09db 100644
---
a/libaccesspoint/src/main/java/cc/mvdan/libaccesspoint/WifiApControl.java
+++
b/libaccesspoint/src/main/java/cc/mvdan/libaccesspoint/WifiApControl.java
@@ -19,6 +19,7 @@ package cc.mvdan.libaccesspoint;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
 import android.os.Build;
 import android.util.Log;
 
@@ -30,6 +31,7 @@ import java.math.BigInteger;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.regex.Pattern;
@@ -308,4 +310,67 @@ public class WifiApControl {
 
 		return result;
 	}
+
+       public interface ReachableClientListener {
+               void onReachableClient(Client c);
+       }
+
+       public void getReachableClients(ReachableClientListener
listener, int timeout) {
+               final List<Client> clients = getClients();
+               if (clients == null) {
+                       return;
+               }
+               for (Client client : clients) {
+                       new IsReachableJob(listener,
timeout).execute(client);
+               }
+       }
+
+       public List<Client> getReachableClientsList(int timeout) {
+               final List<Client> result = new ArrayList<>();
+               getReachableClients(new
SyncReachableClientListener(result), timeout);
+               return result;
+       }
+
+       private class IsReachableJob extends AsyncTask<Client, Void,
Client> {
+               private ReachableClientListener listener;
+               private int timeout;
+
+               public IsReachableJob(ReachableClientListener listener,
int timeout) {
+                       this.listener = listener;
+                       this.timeout = timeout;
+               }
+
+               @Override
+               protected Client doInBackground(Client ...clients) {
+                       final Client client = clients[0];
+                       try {
+                               if
(InetAddress.getByName(client.IPAddr).isReachable(timeout)) {
+                                       return client;
+                               }
+                       } catch (IOException e) {
+                               Log.e(TAG, "", e);
+                       }
+                       return null;
+               }
+
+               @Override
+               protected void onPostExecute(Client reachable) {
+                       if (reachable != null) {
+                               listener.onReachableClient(reachable);
+                       }
+               }
+       }
+
+       private class SyncReachableClientListener implements
ReachableClientListener {
+
+               private final List<Client> syncResult;
+
+               public SyncReachableClientListener(final List<Client>
result) {
+                       syncResult =
Collections.synchronizedList(result);
+               }
+
+               public void onReachableClient(Client client) {
+                       syncResult.add(client);
+               }
+       }
 }

On Tue, May 12, 2015, at 10:58 AM, Nathan of Guardian wrote:
> Some help for Daniel from F-Droid project? This is a neat bit of code
> that allows apps to directly setup wifi-tether hotspots, which is part
> of how we do appswap sharing in F-Droid. 
> 
> ----- Original message -----
> From: Daniel Martí <mvdan at mvdan.cc>
> Subject: libaccesspoint concurrency help
> Date: Tue, 12 May 2015 15:53:52 +0200
> 
> Hello guys,
> 
> So I've been working on libaccesspoint today, got most features up and
> running: https://github.com/mvdan/libaccesspoint
> 
> There is only one problem - the list of connected devices is gotten
> through ARP, which is cached for up to a few minutes, so you may well be
> getting devices that have been disconnected for a bit.
> 
> So I'm doing another method for getting clients which are reachable,
> which seems like a general case and should be in the library.
> "Reachable" is the best way to implement "currently connected" that I
> found.
> 
> Obviously I cannot do the network I/O of trying to resolve each IP
> address on the UI thread. So ideally, for N ip addresses I would fire up
> N threads, each would find if the IP address is reachable, and then I
> would collect the results and construct another list consisting only of
> the IP addresses which were reachable.
> 
> Seems easy right? Should be. In Go I could do this with channels and
> WaitGroups in 20 lines at most. But I'm not used to concurrency in Java
> and so I've been stuck with this for hours.
> 
> I'm attaching the diff I currently have. It is very, very wrong. So I'm
> asking for pointers because google doesn't seem to be able to answer
> "how to write sane concurrency in Java" for me :)
> 
> And of course, pull requests welcome if anyone wants to give it a go.
> 
> -- 
> Daniel Martí - mvdan at mvdan.cc - http://mvdan.cc/
> PGP: A9DA 13CD F7A1 4ACD D3DE  E530 F4CA FFDB 4348 041C
> 
> 
> -- 
>   Nathan of Guardian
>   nathan at guardianproject.info


-- 
  Nathan of Guardian
  nathan at guardianproject.info


More information about the guardian-dev mailing list