1717
1818package net .openhft .affinity ;
1919
20- import org .jetbrains .annotations .NotNull ;
20+ import net .openhft .affinity .lockchecker .FileLockBasedLockChecker ;
21+ import net .openhft .affinity .lockchecker .LockChecker ;
2122import org .slf4j .Logger ;
2223import org .slf4j .LoggerFactory ;
2324
2425import java .io .*;
25- import java .text .SimpleDateFormat ;
26- import java .util .Date ;
2726
2827/**
2928 * @author Rob Austin.
@@ -35,61 +34,49 @@ enum LockCheck {
3534 private static final String OS = System .getProperty ("os.name" ).toLowerCase ();
3635 static final boolean IS_LINUX = OS .startsWith ("linux" );
3736 private static final int EMPTY_PID = Integer .MIN_VALUE ;
38- private static SimpleDateFormat df = new SimpleDateFormat ("yyyy.MM" + ".dd 'at' HH:mm:ss z" );
37+
38+
39+ private static final LockChecker lockChecker = FileLockBasedLockChecker .getInstance ();
3940
4041 static long getPID () {
4142 String processName =
4243 java .lang .management .ManagementFactory .getRuntimeMXBean ().getName ();
4344 return Long .parseLong (processName .split ("@" )[0 ]);
4445 }
4546
46- public static boolean isCpuFree (int cpu ) {
47+ static boolean canOSSupportOperation () {
48+ return IS_LINUX ;
49+ }
4750
48- if (!IS_LINUX )
51+ public static boolean isCpuFree (int cpu ) {
52+ if (!canOSSupportOperation ())
4953 return true ;
5054
51- final File file = toFile (cpu );
52- final boolean exists = file .exists ();
53-
54- if (!exists ) {
55+ if (isLockFree (cpu )) {
5556 return true ;
5657 } else {
5758 int currentProcess = 0 ;
5859 try {
59- currentProcess = getProcessForCpu (file );
60+ currentProcess = getProcessForCpu (cpu );
6061 } catch (RuntimeException | IOException e ) {
6162 LOGGER .warn ("Failed to determine process on cpu " + cpu , e );
6263 e .printStackTrace ();
6364 return true ;
6465 }
65- if (currentProcess == EMPTY_PID ) {
66- file .delete ();
67- return true ;
68- }
6966 if (!isProcessRunning (currentProcess )) {
70- file . delete ( );
67+ lockChecker . releaseLock ( cpu );
7168 return true ;
7269 }
7370 return false ;
7471 }
7572 }
7673
77- @ NotNull
78- static File toFile (int core ) {
79- return new File (tmpDir (), "cpu-" + core + ".lock" );
80- }
81-
82- static void replacePid (int core , long processID ) throws IOException {
83- replacePid (toFile (core ), processID );
84- }
85-
86- private static void replacePid (File file , long processID ) throws IOException {
87- file .delete ();
88- storePid (processID , file );
74+ static void replacePid (int cpu , long processID ) throws IOException {
75+ storePid (processID , cpu );
8976 }
9077
9178 static boolean isProcessRunning (long pid ) {
92- if (IS_LINUX )
79+ if (canOSSupportOperation () )
9380 return new File ("/proc/" + pid ).exists ();
9481 else
9582 throw new UnsupportedOperationException ("this is only supported on LINUX" );
@@ -99,55 +86,41 @@ static boolean isProcessRunning(long pid) {
9986 * stores the pid in a file, named by the core, the pid is written to the file with the date
10087 * below
10188 */
102- private synchronized static void storePid (long processID , File coreFile ) throws IOException {
103- try (Writer writer = new BufferedWriter (new OutputStreamWriter (
104- new FileOutputStream (coreFile , false ), "utf-8" ))) {
105- String processIDStr = Long .toString (processID );
106- writer .write (processIDStr + "\n " + df .format (new Date ()));
89+ private synchronized static void storePid (long processID , int cpu ) throws IOException {
90+ if (!lockChecker .obtainLock (cpu , Long .toString (processID ))) {
91+ throw new IOException (String .format ("Cannot obtain file lock for cpu %d" , cpu ));
10792 }
10893 }
10994
110- static int getProcessForCpu (int core ) throws IOException {
111- return getProcessForCpu ( toFile ( core ) );
95+ private synchronized static boolean isLockFree (int id ) {
96+ return lockChecker . isLockFree ( id );
11297 }
11398
114- private static int getProcessForCpu (@ NotNull File coreFile ) throws IOException {
115- try (BufferedReader reader = new BufferedReader (new InputStreamReader (
116- new FileInputStream (coreFile ), "utf-8" ))) {
99+ static int getProcessForCpu (int core ) throws IOException {
100+ String meta = lockChecker .getMetaInfo (core );
117101
118- final String firstLine = reader .readLine ();
119- if (firstLine == null ) {
120- LOGGER .warn ("Empty lock file {}" , coreFile .getAbsolutePath ());
121- return EMPTY_PID ;
122- }
123- String s = firstLine .trim ();
102+ if (meta != null && !meta .isEmpty ()) {
124103 try {
125- return Integer .parseInt (s );
126- } catch (RuntimeException e ) {
127- LOGGER .warn ("Corrupt lock file {}: first line = '{}'" , coreFile .getAbsolutePath (), firstLine );
128- e .printStackTrace ();
129- return EMPTY_PID ;
104+ return Integer .parseInt (meta );
105+ } catch (NumberFormatException e ) {
106+ //nothing
130107 }
131108 }
132- }
133-
134- private static File tmpDir () {
135- final File tempDir = new File (System .getProperty ("java.io.tmpdir" ));
136-
137- if (!tempDir .exists ())
138- tempDir .mkdirs ();
139-
140- return tempDir ;
109+ return EMPTY_PID ;
141110 }
142111
143112 static void updateCpu (int cpu ) {
144- if (!IS_LINUX )
113+ if (!canOSSupportOperation () )
145114 return ;
146115 try {
147- replacePid (toFile ( cpu ) , getPID ());
116+ replacePid (cpu , getPID ());
148117 } catch (IOException e ) {
149118 LOGGER .warn ("Failed to update lock file for cpu " + cpu , e );
150119 e .printStackTrace ();
151120 }
152121 }
122+
123+ public static void releaseLock (int cpu ) {
124+ lockChecker .releaseLock (cpu );
125+ }
153126}
0 commit comments