add file locking system to avoid race conditions on db files

Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
Alessandro Comodi 2022-03-04 12:40:22 +01:00
parent 6c4188a520
commit dcb1743764
2 changed files with 32 additions and 0 deletions

View File

@ -10,6 +10,7 @@
# SPDX-License-Identifier: ISC
from collections import namedtuple
from prjxray import bitstream
from prjxray import util
from prjxray.grid_types import BlockType
import enum
@ -84,15 +85,21 @@ class TileSegbits(object):
if tile_db.ppips is not None:
with open(tile_db.ppips) as f:
util.lock_file(f, 10)
self.ppips = read_ppips(f)
util.unlock_file(f)
if tile_db.segbits is not None:
with open(tile_db.segbits) as f:
util.lock_file(f, 10)
self.segbits[BlockType.CLB_IO_CLK] = read_segbits(f)
util.unlock_file(f)
if tile_db.block_ram_segbits is not None:
with open(tile_db.block_ram_segbits) as f:
util.lock_file(f, 10)
self.segbits[BlockType.BLOCK_RAM] = read_segbits(f)
util.unlock_file(f)
for block_type in self.segbits:
for feature in self.segbits[block_type]:

View File

@ -8,10 +8,12 @@
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import fcntl
import math
import os
import random
import re
import signal
import yaml
from .roi import Roi
@ -254,8 +256,10 @@ def parse_db_line(line):
def parse_db_lines(fn):
with open(fn, "r") as f:
lock_file(f, 10)
for line in f:
yield line, parse_db_line(line)
unlock_file(f)
def write_db_lines(fn, entries, track_origin=False):
@ -269,8 +273,10 @@ def write_db_lines(fn, entries, track_origin=False):
new_lines.append(new_line)
with open(fn, "w") as f:
lock_file(f, 10)
for line in sorted(new_lines):
print(line, file=f)
unlock_file(f)
def parse_tagbit(x):
@ -402,3 +408,22 @@ def add_bool_arg(parser, yes_arg, default=False, **kwargs):
yes_arg, dest=dest, action='store_true', default=default, **kwargs)
parser.add_argument(
'--no-' + dashed, dest=dest, action='store_false', **kwargs)
def timeout_handler(signum, frame):
raise Exception("ERROR: could not lock file!")
def lock_file(fd, timeout):
try:
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout)
fcntl.flock(fd.fileno(), fcntl.LOCK_EX)
signal.alarm(0)
except Exception as e:
print(e)
exit(1)
def unlock_file(fd):
fcntl.flock(fd.fileno(), fcntl.LOCK_UN)