2008-02-11 [colin] 3.3.0cvs5
authorColin Leroy <colin@colino.net>
Mon, 11 Feb 2008 07:51:15 +0000 (07:51 +0000)
committerColin Leroy <colin@colino.net>
Mon, 11 Feb 2008 07:51:15 +0000 (07:51 +0000)
* src/main.c
Implement support for future /dev/mem_notify.
This Linux kernel feature will allow applications
to be notified that memory has to be freed
before getting OOM-killed. For more information:
http://lwn.net/Articles/267013/

ChangeLog
PATCHSETS
configure.ac
src/main.c

index 398b1bbbb83537639bb141dac1e50cb36522dedb..0e28aca5ce78792b7658dee12e9271e0257f4e62 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-02-11 [colin]     3.3.0cvs5
+
+       * src/main.c
+               Implement support for future /dev/mem_notify.
+               This Linux kernel feature will allow applications
+               to be notified that memory has to be freed
+               before getting OOM-killed. For more information:
+               http://lwn.net/Articles/267013/
+
 2008-02-10 [paul]      3.3.0cvs4
 
        * src/Makefile.am
index f2336cd8d0208fd8cfc7684c6018d9ea0a008390..23f3d7e517f2bdbc8c4dfde8cd78013be9671790 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.115.2.184 -r 1.115.2.185 src/main.c;  ) > 3.3.0cvs2.patchset
 ( cvs diff -u -r 1.4.2.60 -r 1.4.2.61 src/gtk/about.c;  ) > 3.3.0cvs3.patchset
 ( cvs diff -u -r 1.155.2.83 -r 1.155.2.84 src/Makefile.am;  cvs diff -u -r 1.83.2.127 -r 1.83.2.128 src/mimeview.c;  cvs diff -u -r 1.30.2.47 -r 1.30.2.48 src/prefs_toolbar.c;  cvs diff -u -r 1.25.2.51 -r 1.25.2.52 src/stock_pixmap.c;  cvs diff -u -r 1.18.2.33 -r 1.18.2.34 src/stock_pixmap.h;  diff -u /dev/null src/pixmaps/mime_text_patch.xpm;  ) > 3.3.0cvs4.patchset
+( cvs diff -u -r 1.115.2.185 -r 1.115.2.186 src/main.c;  ) > 3.3.0cvs5.patchset
index e3e4ebba4f0784f5cc49e24dc37413becb8c7cef..89611b2543d4e108413f57bbf0ed01591491e2a5 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=3
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=4
+EXTRA_VERSION=5
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 245d30812a304a9d2e717463132ca21d51b926f9..b5278e867a8388f0f1256eb6ecda09f940d5e60c 100644 (file)
 #include <sys/types.h>
 #ifdef G_OS_UNIX
 #  include <signal.h>
+#  include <errno.h>
+#  include <fcntl.h>
 #endif
 #ifdef HAVE_LIBSM
 #include <X11/SM/SMlib.h>
-#include <fcntl.h>
 #endif
 
 #include "wizard.h"
@@ -213,6 +214,9 @@ static void send_queue                      (void);
 static void initial_processing         (FolderItem *item, gpointer data);
 static void quit_signal_handler         (int sig);
 static void install_basic_sighandlers   (void);
+#if (defined linux && defined SIGIO)
+static void install_memory_sighandler   (void);
+#endif
 static void exit_claws                 (MainWindow *mainwin);
 
 #ifdef HAVE_NETWORKMANAGER_SUPPORT
@@ -962,6 +966,9 @@ int main(int argc, char *argv[])
        crash_install_handlers();
 #endif
        install_basic_sighandlers();
+#if (defined linux && defined SIGIO)
+       install_memory_sighandler();
+#endif
        sock_init();
 
        /* check and create unix domain socket for remote operation */
@@ -2287,6 +2294,57 @@ static void install_basic_sighandlers()
 #endif /* !G_OS_WIN32 */
 }
 
+#if (defined linux && defined SIGIO)
+static int mem_notify_fd = 0;
+
+static gboolean clean_caches(gpointer unused)
+{
+       if (static_mainwindow && static_mainwindow->lock_count > 0)
+               return TRUE;
+       debug_print("/dev/mem_notify: callback: Freeing some memory now!\n");
+       folder_clean_cache_memory_force();
+       return FALSE;
+}
+
+static void memory_signal_handler(int sig)
+{
+       debug_print("/dev/mem_notify: Kernel says we should free up some memory!\n");
+       g_timeout_add(10, clean_caches, NULL); 
+}
+
+static void install_memory_sighandler()
+{
+       sigset_t    mask;
+       struct sigaction act;
+       int flags;
+
+       mem_notify_fd = open("/dev/mem_notify", O_RDONLY|O_NONBLOCK);
+       if (mem_notify_fd == -1) {
+               debug_print("/dev/mem_notify not available (%s)\n", 
+                       strerror(errno));
+               return;
+       }
+       
+       fcntl(mem_notify_fd, F_SETOWN, getpid());
+       flags = fcntl(mem_notify_fd, F_GETFL);
+       fcntl(mem_notify_fd, flags|FASYNC);
+
+       sigemptyset(&mask);
+
+       sigaddset(&mask, SIGIO);
+
+       act.sa_handler = memory_signal_handler;
+       act.sa_mask    = mask;
+       act.sa_flags   = 0;
+
+       sigaction(SIGIO, &act, 0);
+
+       sigprocmask(SIG_UNBLOCK, &mask, 0);
+
+       debug_print("/dev/mem_notify: installed handler\n");
+}
+#endif /* linux && SIGIO */
+
 #ifdef MAEMO
 osso_context_t *get_osso_context(void)
 {