Enforce just one instance?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Enforce just one instance?

Post by pgimeno »

monolified's approach has the advantages of being cross-platform, atomic and standard, and doesn't give false positives in case of a crash, over any other solution presented so far.

Code: Select all

local instance_detector -- keep it live until the application finishes
do
  local tcp = require 'socket'.tcp
  instance_detector = tcp()
  if not instance_detector:bind('127.0.0.1', 16219) then
    print("An instance is already running, closing")
    return love.event.quit()
  end
end
User avatar
togFox
Party member
Posts: 770
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: Enforce just one instance?

Post by togFox »

Some great ideas. I was wondering if Love2D can check for all instance/apps/programs running and then if one of those matches my program then I can quit?

I don't want to troll through every service but when I open task manager I can see there are five apps running now (for example) so I'd just step through that looking for a text value. Possible?
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
MrFariator
Party member
Posts: 509
Joined: Wed Oct 05, 2016 11:53 am

Re: Enforce just one instance?

Post by MrFariator »

I think you can probably do that via C FFI, but you'd have to do it on a per-platform basis. Additionally, I don't think reading the application window or process name is a good idea, as that can, depending on circumstances, create false-positives. Sure, games' titles often can be a bit more unique and less generic, but you'd still have to make sure that your process' name doesn't interfere with anything else. This approach also doesn't necessarily solve the problem in the event the application hangs, but still remains in the active processes list for some time before exiting. Furthermore, there may be some circumstances where your application doesn't have the rights to read other processes' titles, but this is probably a platform and environment specific thing.

The code pgimeno posted basically already does all you need - just make the port number configurable and you're good to go.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Enforce just one instance?

Post by grump »

Instead of making the port configurable, I propose this hybrid solution (pseudo code):

Code: Select all

function other_instance_running()
	if exists(lockfile) then
		port = read_port_from(lockfile)
		socket = bind_local_socket(port)
		if not succeeded(socket) then
			return true
		end
		delete(lockfile)
	end
	return false
end

function start_instance_guard()
	repeat
		port = love.math.random(49152, 65535) -- or loop over the whole range
		socket = bind_local_socket(port)
	until succeeded(socket)
	write_port_to(lockfile, port)	
end

function love.quit()
	delete(lockfile)
	return false
end
edit: fixed some ambiguity
Last edited by grump on Wed Mar 31, 2021 11:37 am, edited 1 time in total.
RNavega
Party member
Posts: 239
Joined: Sun Aug 16, 2020 1:28 pm

Re: Enforce just one instance?

Post by RNavega »

My only concern is which method uses less (CPU) resources. I don't know if using a listening socket to behave like a global mutex in this way involves any redundant polling from the OS or not.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Enforce just one instance?

Post by pgimeno »

It's not even listening. I doubt it consumes CPU.

My concern with grump's approach is the lack of atomicity (a time-of-check to time-of-use race; if two instances are launched at the same time, it's possible that neither detects the other), but I guess that's too strict for practical situations.
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Enforce just one instance?

Post by grump »

Yeah good point. Use this only if it's not actually critical for your game. Otherwise use FFI to get exclusive file locking.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Enforce just one instance?

Post by ivan »

The socket solution is clever but it's hacky.
We need to open an issue request to include love.filesystem.lock in the next version of love2d.
lfs.lock seems to available in similar libraries
grump
Party member
Posts: 947
Joined: Sat Jul 22, 2017 7:43 pm

Re: Enforce just one instance?

Post by grump »

ivan wrote: Wed Mar 31, 2021 12:42 pm We need to open an issue request to include love.filesystem.lock in the next version of love2d.
If you want this to happen, you have to submit a pull request yourself, and PhysFS does not seem to support file locking, so it's not going to integrate super well with the filesystem API.

And even then... LÖVE is moving at a glacier's pace with its weird release cycle. Not enough manpower I guess.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Enforce just one instance?

Post by ivan »

Yea, I hear you grump. I'm not in a rush, but file locking seems like a super basic operation that should be available in love.filesystem by default
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot], Nabeel and 38 guests