device filtering support

Pete Batard pete at akeo.ie
Sun Feb 5 19:35:58 EST 2012


On 2012.02.05 22:09, Vitali Lovich wrote:
> Yes, but let's say application 1 is communicating with the backend service. application 2 starts up&  kills the backend service because it has a newer version.  obviously you've just broken the ability for application 1 to continue working.  That's what I'm saying.

Except, at least on Windows, the private data we provide is the same, 
and to uniquely identify a libusb device, we use a hash that is tagged 
to an OS device property that is guaranteed to be unique (doesn't change 
within the same session - shouldn't even change after reboot actually). 
This is what is used in new enum on Windows, and what I think should be 
used across platforms. The locks, contexts, etc. would still be handled 
by the app in the library part, not the process. Maybe that's what you 
have in mind (in case we want to have a centralized way to prevent 
access to the same device between apps), but it doesn't make sense to do 
so when we'd still be unable to detect any non-libusbx app accessing the 
same device.
Again, I think you are misconstruing what I have in mind, because the 
plan has never been to take the complete libusb_device structure as it 
exists now, and move it wholesale into a separate process. It just 
wouldn't make sense. But all the unique & (session) invariant USB 
specific data that we can obtain from the OS can most definitely be 
moved there.

As I stated, the goal of the process is mostly to replace stuff we 
should be able to obtain cached from the OS but which, on some platforms 
we can't. Hence, nothing that is meant to be libusbx-internal only, such 
as locks and contextes would ever go there.

So, the way I see it, app 2 kills the backend service and starts a newer 
one (which is a big if, because that should only happen if we have API 
breakage, such as new data items, which as I mentioned, is not something 
we will see on regular basis). Well, the data app 1 received from the 
enum process is still 100% valid, whether the enum process runs or not 
(at least, as long as it doesn't receive a hotplug notification - the 
only issue we face is if there's a hotplug we miss during respawn, which 
I don't see as something we should concern ourselves with). The 
descriptors are the same, the file handles are OS handles, anything that 
was returned by the OS is still valid. What's more, at least on Windows, 
we use hashes indexed on unique data from the OS (i.e. also unchanged), 
so even if our process enum list gets reindexed somehow, when app 1 or 2 
asks for an update with regards to device with hash 1234abc, it gets the 
_exact_ same data, regardless of whether the old or new enum process is 
the one that feeds it.

> The point is the complexity is greater than the complexity of not doing it&  solving it within libusb.  The other thing to note is that you solved it within libwdi (which actually required this kind of solution because of UAC)&  libwdi has a completely different usage (i.e. 1 spawned process per libwdi instance - it's not shared among several processes).  I have actually done this type of thing as well&  it's never as straight-forward as you would like, even with a static API.

How about we let an actual implementation proposal decide then. Will 
have to come after we sorted hotplug, but now I really wouldn't mind 
demonstrating which of "it's so complex it'll never fly" or "actually 
it's not that difficult" is right.

> Then you're just engineering a solution without having a good grasp of what you're trying to solve.

I believe I do. The enum data we want is very static, as it should, 
because unless someone is plugging and unplugging devices (or switching 
confs, which, should result in hotplug on Windows and is not possible 
for WinUSB). Descriptors don't change, accessors (OS specific paths or 
identifiers to access a device) don't change, and our private data 
shouldn't either. You can go over both the public and private device 
data that libusb currently handle, and you should find that, there's 
about 4 items in there that we can keep in the library (lock, refcnt, 
ctx, possibly session_data) while all the rest can be provided/queried 
from an external source. And I don't really see a major obstruction to 
such a split up at the moment.

Therefore, we should be able to query the OS once for it, add hotplug, 
and work with that.

> The generic enum will not go away.

Good.

> Again, the first step is to prove the problem exists&  understand it.

Not if solving it is not that difficult, and brings other benefits.

> Again, you're missing the point; app1 uses backendv1, app2 uses backendv2.  Both are running at the same time.  You can't just go kill it.

Again, why? Do any of the apps expect enum data that is unique to a 
specific session of the enum process. If that's the case, then we've 
done a poor job with it, because it shouldn't be, and that's definitely 
not the way I conceive it.

Therefore, the way I see it is you can kill and respawn the process as 
many times as you want, and running apps will still be fine. Once you've 
queried and opened your device, you can kill the process if you want, it 
won't matter one bit - you will have been provided with data that is 
session-invariant and that you can use for device access.

The process is a replacement for what we want the OS to cache and be 
able to feed us at all times. Not a "let's move a whole internal libusb 
call into a process" (though most of neum would probably end up there).

> What I meant by that is that you'd have to maintain a compatibility matrix of which versions are safe to kill (i.e. the new version is a strict backwards-compatible superset)&  which ones aren't (i.e. must be able to run co-operatively with an older version).  The other approach is that every new backend version is it's own process&  rendevouz works magically* in a version-safe manner, but that essentially gets us back to the original problem with multiple processes doing this.

For APIs that I don't see changing more than once a year at worst, and 
where every subsequent one is expected to be a superset.

Regards,

/Pete



More information about the libusbx mailing list