]> mj.ucw.cz Git - libucw.git/commitdiff
Creation of temporary files is now thread-safe (ugh).
authorMartin Mares <mj@ucw.cz>
Sat, 9 Dec 2006 19:00:46 +0000 (20:00 +0100)
committerMartin Mares <mj@ucw.cz>
Sat, 9 Dec 2006 19:00:46 +0000 (20:00 +0100)
lib/fastbuf.h
lib/fb-temp.c

index c5e1deb860f8610ed5cbb5eba03f6723e78c9cd7..27f0f584cefc28143d275e63be00a4bbcc7ae8fb 100644 (file)
@@ -88,6 +88,9 @@ struct fastbuf *bfdopen(int fd, uns buflen);
 struct fastbuf *bfdopen_shared(int fd, uns buflen);
 void bfilesync(struct fastbuf *b);
 
+#define TEMP_FILE_NAME_LEN 256
+void temp_file_name(byte *name);
+
 /* FastIO on in-memory streams */
 
 struct fastbuf *fbmem_create(unsigned blocksize);      /* Create stream and return its writing fastbuf */
index b8189ab933497315eb71aef37201fcb4d3c30b5f..ed7623ffc85edc5989678a5be0106c5124064881 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     UCW Library -- Temporary Fastbufs
  *
- *     (c) 2002--2004 Martin Mares <mj@ucw.cz>
+ *     (c) 2002--2006 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
 #include <unistd.h>
 #include <sys/fcntl.h>
 
-static byte *temp_template = "/tmp/temp%d.%d";
+static byte *temp_prefix = "/tmp/temp";
 
 static struct cf_section temp_config = {
   CF_ITEMS {
-    CF_STRING("Template", &temp_template),
+    CF_STRING("Prefix", &temp_prefix),
     CF_END
   }
 };
 
-static void CONSTRUCTOR temp_init_config(void)
+static void CONSTRUCTOR temp_global_init(void)
 {
   cf_declare_section("Tempfiles", &temp_config, 0);
 }
 
+#ifdef CONFIG_UCW_THREADS
+#include <pthread.h>
+
+static pthread_key_t temp_counter_key;
+
+static void CONSTRUCTOR
+temp_key_init(void)
+{
+  if (pthread_key_create(&temp_counter_key, NULL) < 0)
+    die("Cannot create fbdir_queue_key: %m");
+}
+
+void
+temp_file_name(byte *buf)
+{
+  int cnt = (int) pthread_getspecific(temp_counter_key);
+  cnt++;
+  pthread_setspecific(temp_counter_key, (void *) cnt);
+
+  int pid = getpid();
+#if 0
+  /* FIXME: This is Linux-specific and not declared anywhere :( */
+  int tid = gettid();
+#else
+  int tid = pid;
+#endif
+  if (pid == tid)
+    sprintf(buf, "%s%d-%d", temp_prefix, pid, cnt);
+  else
+    sprintf(buf, "%s%d-%d-%d", temp_prefix, pid, tid, cnt);
+}
+
+#else
+
+void
+temp_file_name(byte *buf)
+{
+  static int cnt;
+  sprintf(buf, "%s%d-%d", temp_prefix, (int)getpid(), cnt++);
+}
+
+#endif
+
 struct fastbuf *
 bopen_tmp(uns buflen)
 {
-  byte buf[256];
+  byte buf[TEMP_FILE_NAME_LEN];
   struct fastbuf *f;
-  static uns temp_counter;
 
-  sprintf(buf, temp_template, (int) getpid(), temp_counter++);
+  temp_file_name(buf);
   f = bopen(buf, O_RDWR | O_CREAT | O_TRUNC, buflen);
   bconfig(f, BCONFIG_IS_TEMP_FILE, 1);
   return f;
 }
+
+#ifdef TEST
+
+#include "lib/getopt.h"
+
+int main(int argc, char **argv)
+{
+  log_init(NULL);
+  if (cf_getopt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) >= 0)
+    die("Hey, whaddya want?");
+
+  struct fastbuf *f = bopen_tmp(65536);
+  bputsn(f, "Hello, world!");
+  bclose(f);
+  return 0;
+}
+
+#endif