mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	spa: alsa,v4l2: avoid double access check on inotify events
Previously both `impl_on_notify_events()` and `process_{device,card}()`
called `check_access()`. Avoid that by merging `ACTION_ADD` and
`ACTION_DISABLE` into a single `ACTION_CHANGE` and let `process_{device,card}()`
call `check_access()` and decide what to do.
(cherry picked from commit ad975c93ee)
			
			
This commit is contained in:
		
							parent
							
								
									37031a21ea
								
							
						
					
					
						commit
						062a1039e9
					
				
					 2 changed files with 47 additions and 69 deletions
				
			
		| 
						 | 
				
			
			@ -32,9 +32,8 @@
 | 
			
		|||
#define MAX_CARDS	64
 | 
			
		||||
 | 
			
		||||
enum action {
 | 
			
		||||
	ACTION_ADD,
 | 
			
		||||
	ACTION_CHANGE,
 | 
			
		||||
	ACTION_REMOVE,
 | 
			
		||||
	ACTION_DISABLE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Used for unavailable devices in the card structure. */
 | 
			
		||||
| 
						 | 
				
			
			@ -726,9 +725,9 @@ static void process_card(struct impl *this, enum action action, struct card *car
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	switch (action) {
 | 
			
		||||
	case ACTION_ADD: {
 | 
			
		||||
		if (!check_access(this, card))
 | 
			
		||||
			return;
 | 
			
		||||
	case ACTION_CHANGE: {
 | 
			
		||||
		check_access(this, card);
 | 
			
		||||
		if (card->accessible && !card->emitted) {
 | 
			
		||||
			int res = emit_added_object_info(this, card);
 | 
			
		||||
			if (res < 0) {
 | 
			
		||||
				if (card->ignored)
 | 
			
		||||
| 
						 | 
				
			
			@ -747,6 +746,14 @@ static void process_card(struct impl *this, enum action action, struct card *car
 | 
			
		|||
							card->card_nr);
 | 
			
		||||
				card->unavailable = false;
 | 
			
		||||
			}
 | 
			
		||||
		} else if (!card->accessible && card->emitted) {
 | 
			
		||||
			card->emitted = false;
 | 
			
		||||
 | 
			
		||||
			if (card->pcm_device_id != ID_DEVICE_NOT_SUPPORTED)
 | 
			
		||||
				spa_device_emit_object_info(&this->hooks, card->pcm_device_id, NULL);
 | 
			
		||||
			if (card->compress_offload_device_id != ID_DEVICE_NOT_SUPPORTED)
 | 
			
		||||
				spa_device_emit_object_info(&this->hooks, card->compress_offload_device_id, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	case ACTION_REMOVE: {
 | 
			
		||||
| 
						 | 
				
			
			@ -764,22 +771,6 @@ static void process_card(struct impl *this, enum action action, struct card *car
 | 
			
		|||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	case ACTION_DISABLE:
 | 
			
		||||
		if (card->emitted) {
 | 
			
		||||
			uint32_t pcm_device_id, compress_offload_device_id;
 | 
			
		||||
 | 
			
		||||
			pcm_device_id = card->pcm_device_id;
 | 
			
		||||
			compress_offload_device_id = card->compress_offload_device_id;
 | 
			
		||||
 | 
			
		||||
			card->emitted = false;
 | 
			
		||||
 | 
			
		||||
			if (pcm_device_id != ID_DEVICE_NOT_SUPPORTED)
 | 
			
		||||
				spa_device_emit_object_info(&this->hooks, pcm_device_id, NULL);
 | 
			
		||||
			if (compress_offload_device_id != ID_DEVICE_NOT_SUPPORTED)
 | 
			
		||||
				spa_device_emit_object_info(&this->hooks, compress_offload_device_id, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -792,7 +783,7 @@ static void process_udev_device(struct impl *this, enum action action, struct ud
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	card = find_card(this, card_nr);
 | 
			
		||||
	if (action == ACTION_ADD && !card)
 | 
			
		||||
	if (action == ACTION_CHANGE && !card)
 | 
			
		||||
		card = add_card(this, card_nr, udev_device);
 | 
			
		||||
 | 
			
		||||
	if (!card)
 | 
			
		||||
| 
						 | 
				
			
			@ -844,18 +835,13 @@ static void impl_on_notify_events(struct spa_source *source)
 | 
			
		|||
 | 
			
		||||
			/* card becomes accessible or not busy */
 | 
			
		||||
			if ((event->mask & (IN_ATTRIB | IN_CLOSE_WRITE))) {
 | 
			
		||||
				bool access;
 | 
			
		||||
				if (sscanf(event->name, "controlC%u", &card_nr) != 1 &&
 | 
			
		||||
				    sscanf(event->name, "pcmC%uD", &card_nr) != 1)
 | 
			
		||||
					continue;
 | 
			
		||||
				if ((card = find_card(this, card_nr)) == NULL)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				access = check_access(this, card);
 | 
			
		||||
				if (access && !card->emitted)
 | 
			
		||||
					process_card(this, ACTION_ADD, card);
 | 
			
		||||
				else if (!access && card->emitted)
 | 
			
		||||
					process_card(this, ACTION_DISABLE, card);
 | 
			
		||||
				process_card(this, ACTION_CHANGE, card);
 | 
			
		||||
			}
 | 
			
		||||
			/* /dev/snd/ might have been removed */
 | 
			
		||||
			if ((event->mask & (IN_IGNORED | IN_MOVE_SELF)))
 | 
			
		||||
| 
						 | 
				
			
			@ -918,7 +904,7 @@ static void impl_on_fd_events(struct spa_source *source)
 | 
			
		|||
	start_inotify(this);
 | 
			
		||||
 | 
			
		||||
	if (spa_streq(action, "change")) {
 | 
			
		||||
		process_udev_device(this, ACTION_ADD, udev_device);
 | 
			
		||||
		process_udev_device(this, ACTION_CHANGE, udev_device);
 | 
			
		||||
	} else if (spa_streq(action, "remove")) {
 | 
			
		||||
		process_udev_device(this, ACTION_REMOVE, udev_device);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -991,7 +977,7 @@ static int enum_cards(struct impl *this)
 | 
			
		|||
		if (udev_device == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		process_udev_device(this, ACTION_ADD, udev_device);
 | 
			
		||||
		process_udev_device(this, ACTION_CHANGE, udev_device);
 | 
			
		||||
 | 
			
		||||
		udev_device_unref(udev_device);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,9 +29,8 @@
 | 
			
		|||
#define MAX_DEVICES	64
 | 
			
		||||
 | 
			
		||||
enum action {
 | 
			
		||||
	ACTION_ADD,
 | 
			
		||||
	ACTION_CHANGE,
 | 
			
		||||
	ACTION_REMOVE,
 | 
			
		||||
	ACTION_DISABLE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct device {
 | 
			
		||||
| 
						 | 
				
			
			@ -362,10 +361,14 @@ static bool check_access(struct impl *this, struct device *device)
 | 
			
		|||
static void process_device(struct impl *this, enum action action, struct device *device)
 | 
			
		||||
{
 | 
			
		||||
	switch (action) {
 | 
			
		||||
	case ACTION_ADD:
 | 
			
		||||
		if (!check_access(this, device))
 | 
			
		||||
			return;
 | 
			
		||||
	case ACTION_CHANGE:
 | 
			
		||||
		check_access(this, device);
 | 
			
		||||
		if (device->accessible && !device->emitted) {
 | 
			
		||||
			emit_object_info(this, device);
 | 
			
		||||
		} else if (!device->accessible && device->emitted) {
 | 
			
		||||
			device->emitted = false;
 | 
			
		||||
			spa_device_emit_object_info(&this->hooks, device->id, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case ACTION_REMOVE: {
 | 
			
		||||
		bool emitted = device->emitted;
 | 
			
		||||
| 
						 | 
				
			
			@ -377,12 +380,6 @@ static void process_device(struct impl *this, enum action action, struct device
 | 
			
		|||
			spa_device_emit_object_info(&this->hooks, id, NULL);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	case ACTION_DISABLE:
 | 
			
		||||
		if (device->emitted) {
 | 
			
		||||
			device->emitted = false;
 | 
			
		||||
			spa_device_emit_object_info(&this->hooks, device->id, NULL);
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -395,7 +392,7 @@ static void process_udev_device(struct impl *this, enum action action, struct ud
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	device = find_device(this, id);
 | 
			
		||||
	if (action == ACTION_ADD && !device)
 | 
			
		||||
	if (action == ACTION_CHANGE && !device)
 | 
			
		||||
		device = add_device(this, id, udev_device);
 | 
			
		||||
 | 
			
		||||
	if (!device)
 | 
			
		||||
| 
						 | 
				
			
			@ -453,13 +450,8 @@ static void impl_on_notify_events(struct spa_source *source)
 | 
			
		|||
			if (!device)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (event->mask & IN_ATTRIB) {
 | 
			
		||||
				bool access = check_access(this, device);
 | 
			
		||||
				if (access && !device->emitted)
 | 
			
		||||
					process_device(this, ACTION_ADD, device);
 | 
			
		||||
				else if (!access && device->emitted)
 | 
			
		||||
					process_device(this, ACTION_DISABLE, device);
 | 
			
		||||
			}
 | 
			
		||||
			if (event->mask & IN_ATTRIB)
 | 
			
		||||
				process_device(this, ACTION_CHANGE, device);
 | 
			
		||||
 | 
			
		||||
			if (event->mask & IN_IGNORED)
 | 
			
		||||
				device->inotify_wd = -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -510,7 +502,7 @@ static void impl_on_fd_events(struct spa_source *source)
 | 
			
		|||
 | 
			
		||||
	if (spa_streq(action, "add") ||
 | 
			
		||||
	    spa_streq(action, "change")) {
 | 
			
		||||
		process_udev_device(this, ACTION_ADD, dev);
 | 
			
		||||
		process_udev_device(this, ACTION_CHANGE, dev);
 | 
			
		||||
	} else if (spa_streq(action, "remove")) {
 | 
			
		||||
		process_udev_device(this, ACTION_REMOVE, dev);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -582,7 +574,7 @@ static int enum_devices(struct impl *this)
 | 
			
		|||
		if (dev == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		process_udev_device(this, ACTION_ADD, dev);
 | 
			
		||||
		process_udev_device(this, ACTION_CHANGE, dev);
 | 
			
		||||
 | 
			
		||||
		udev_device_unref(dev);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue