Re: Automatic refresh for local Maildir's mail counts -- an attempt based on named pipes
Linux-Fan <Ma_Sys.ma-S0/[email protected]> Mon, 26 Mar 2018 23:57:23 +0200
| Newsgroups | gmane.mail.cone |
|---|---|
| Message-ID | <cone.1522101443.992217.7781.1000@masysma-3> |
This is a MIME GnuPG-signed message. If you see this text, it means that
your E-mail or Usenet software does not support MIME signed messages.
The Internet standard for MIME PGP messages, RFC 2015, was published in 1996.
To open this message correctly you will need to install E-mail or Usenet
software that supports modern Internet standards.
--===============7516850857896640539==
Content-Type: multipart/signed;
boundary="=_masysma-3-7781-1522101443-0001";
micalg=pgp-sha1; protocol="application/pgp-signature"
This is a MIME GnuPG-signed message. If you see this text, it means that
your E-mail or Usenet software does not support MIME signed messages.
The Internet standard for MIME PGP messages, RFC 2015, was published in 1996.
To open this message correctly you will need to install E-mail or Usenet
software that supports modern Internet standards.
--=_masysma-3-7781-1522101443-0001
Content-Type: multipart/mixed; boundary="=_masysma-3-1522101443-0000"
This is a MIME-formatted message. If you see this text it means that your
E-mail software does not support MIME-formatted messages.
--=_masysma-3-1522101443-0000
Content-Type: text/plain; format=flowed; delsp=yes; charset="UTF-8"
Content-Disposition: inline
Content-Transfer-Encoding: 7bit
Sam Varshavchik writes:
> Linux-Fan writes:
>
>> The attached patch thus implements polling in an own location which
>> means it only happens every `mailCheckInterval` (worst case: 300)
>> seconds.
>>
>> My questions are now as follows:
>>
>> * Is the idea implemented by the attached patch safe enough to be
>> included in Cone?
>
> The general idea is correct.
>
>> * What can I do to have the polling mechanism which is already in
>> use in Cone also poll my named pipe file descriptor such that mail
>> counts are immediately updated?
>
> I think all you need to do is add your named pipe's descriptor to the fds
> vector, that gets passed to poll(). This will include the named pipe in the
> list of file descriptor that gets monitored, by the main event loop.
Thank you very much for the explanation.
The actual error (why I initially got endless loops when trying to do this),
was with my understanding of named pipes: What actually caused the endless
loop was that whenever I notified Cone from offlineimap, the named pipe got
closed in the process, causing POLLHUP to be returned (immediately) on all
subsequent poll invocations.
I have now fixed this by re-opening the file descriptor once POLLHUP is
returned and now it works as expected. See attached
`patch_cone_refresh_with_named_pipe_2.diff`.
Yours Faithfully
Linux-Fan
--=_masysma-3-1522101443-0000
Content-Disposition: attachment;
FILENAME="patch_cone_refresh_with_named_pipe_2.diff"
Content-Type: text/x-diff; charset="UTF-8"
Content-Transfer-Encoding: 7bit
diff -Nau -x Makefile.in -x Makefile -x .deps -x '*.cache' -x buildversion.H -x '*.log' -x config.status -r cone-beforechg/cone/cone.C cone-0.96.2.20180216/cone/cone.C
--- cone-beforechg/cone/cone.C 2018-03-25 16:10:45.317386165 +0200
+++ cone-0.96.2.20180216/cone/cone.C 2018-03-26 23:12:53.182300974 +0200
@@ -429,6 +429,7 @@
myServer **selectedServer)
{
CursesHierarchy hierarchy_screen( &myServer::hierarchy, mainScreen);
+ myServer::setCursesHierarchyPointerForRefreshing(&hierarchy_screen);
titleBar->setTitles(_("FOLDERS"), "");
@@ -474,6 +475,8 @@
*selectedFolder=hierarchy_screen.folderSelected;
if (selectedServer)
*selectedServer=hierarchy_screen.serverSelected;
+
+ myServer::setCursesHierarchyPointerForRefreshing(NULL);
}
void hierarchyScreen(void *dummy)
@@ -1025,6 +1028,8 @@
delete myServer::remoteConfigAccount;
myServer::remoteConfigAccount=NULL;
}
+
+ myServer::closePollForRefreshMessageCount();
}
//
@@ -1142,7 +1147,7 @@
int recover=0;
Macros macroBuffer;
- while ((optc=getopt(argc, argv, "vrCc:")) != -1)
+ while ((optc=getopt(argc, argv, "vrCc:m:")) != -1)
{
switch (optc) {
case 'v':
@@ -1151,6 +1156,16 @@
case 'r':
recover=1;
break;
+ case 'm':
+ // try to delete if existent, ignore fail
+ unlink(optarg);
+ if(mkfifo(optarg, 0644) < 0)
+ {
+ perror("Failed to create FIFO");
+ exit(1);
+ }
+ myServer::setPollForRefreshMessageCount(optarg);
+ break;
case 'c':
myServer::configDir=optarg;
diff -Nau -x Makefile.in -x Makefile -x .deps -x '*.cache' -x buildversion.H -x '*.log' -x config.status -r cone-beforechg/cone/curseshierarchy.C cone-0.96.2.20180216/cone/curseshierarchy.C
--- cone-beforechg/cone/curseshierarchy.C 2018-03-25 16:10:45.301386438 +0200
+++ cone-0.96.2.20180216/cone/curseshierarchy.C 2018-03-25 17:08:13.627911893 +0200
@@ -985,6 +985,26 @@
me->processDeletedFolder(parent, deleted, updatedFolder);
}
+bool CursesHierarchy::RefreshIterator::visit(Hierarchy::Folder* f)
+{
+ if(f != NULL && this->cs != NULL)
+ f->updateInfo(this->cs, true);
+ return true;
+}
+
+bool CursesHierarchy::RefreshIterator::visit(Hierarchy::Server* s)
+{
+ if(s != NULL)
+ this->cs = s->getServer();
+ return true;
+}
+
+void CursesHierarchy::refreshAllFolders()
+{
+ RefreshIterator iterator;
+ getHierarchy()->root.prefixIterate(iterator);
+}
+
///////////
bool CursesHierarchy::processKey(const Curses::Key &key)
{
diff -Nau -x Makefile.in -x Makefile -x .deps -x '*.cache' -x buildversion.H -x '*.log' -x config.status -r cone-beforechg/cone/curseshierarchy.H cone-0.96.2.20180216/cone/curseshierarchy.H
--- cone-beforechg/cone/curseshierarchy.H 2018-03-25 16:10:45.321386096 +0200
+++ cone-0.96.2.20180216/cone/curseshierarchy.H 2018-03-25 17:10:14.744631348 +0200
@@ -61,6 +61,14 @@
};
+ class RefreshIterator: public Hierarchy::EntryIterator {
+ private:
+ myServer* cs = NULL;
+ public:
+ bool visit(Hierarchy::Folder* f);
+ bool visit(Hierarchy::Server* s);
+ };
+
public:
friend class DrawIterator;
@@ -84,6 +92,7 @@
bool drawErase(Hierarchy::Server *server, bool doErase);
void visible(Hierarchy::Entry *e);
+ void refreshAllFolders();
private:
bool drawErase(std::string str1, int col1,
diff -Nau -x Makefile.in -x Makefile -x .deps -x '*.cache' -x buildversion.H -x '*.log' -x config.status -r cone-beforechg/cone/myserver.C cone-0.96.2.20180216/cone/myserver.C
--- cone-beforechg/cone/myserver.C 2018-03-25 16:10:45.313386233 +0200
+++ cone-0.96.2.20180216/cone/myserver.C 2018-03-26 23:37:31.227691345 +0200
@@ -23,6 +23,7 @@
#include <fcntl.h>
#include <pwd.h>
#include <unistd.h>
+#include <poll.h>
#include <iostream>
@@ -42,6 +43,10 @@
extern void folderIndexScreen(void *);
extern void hierarchyScreen(void *);
+string myServer::pollForRefreshMessageCount = "";
+int myServer::pollFDForRefreshMessageCount = -1;
+CursesHierarchy* myServer::cursesHierarchyForRefreshing = NULL;
+
myServer::myServer(string name, string urlArg)
: serverName(name), url(urlArg), mailCheckInterval(300), server(NULL),
currentFolder(NULL), hierarchyEntry(NULL)
@@ -273,6 +278,13 @@
if (alarmCalled)
continue; // Something might've happened...
+ struct pollfd pollFDForRefresh = {
+ myServer::pollFDForRefreshMessageCount,
+ POLLIN,
+ 0
+ };
+ fds.push_back(pollFDForRefresh);
+
if (mail::account::poll(fds, ioTimeout) < 0)
{
if (errno != EINTR)
@@ -281,6 +293,22 @@
break;
}
}
+
+ char buf[128];
+ int pollev = fds.back().revents;
+ fds.pop_back();
+ if((pollev & POLLIN) &&
+ read(myServer::pollFDForRefreshMessageCount,
+ buf, sizeof(buf)) > 0 &&
+ myServer::pollFDForRefreshMessageCount != -1 &&
+ myServer::cursesHierarchyForRefreshing != NULL)
+ myServer::cursesHierarchyForRefreshing->
+ refreshAllFolders();
+ if(pollev & POLLHUP) {
+ myServer::closePollForRefreshMessageCount();
+ if(myServer::pollForRefreshMessageCount != "")
+ myServer::openPollFDForRefreshMessageCount();
+ }
}
statusBar->notbusy();
@@ -1032,3 +1060,37 @@
finishCheckingNewMail();
}
+
+void myServer::setPollForRefreshMessageCount(string fn)
+{
+ myServer::pollForRefreshMessageCount = fn;
+ myServer::openPollFDForRefreshMessageCount();
+}
+
+void myServer::openPollFDForRefreshMessageCount()
+{
+ if((myServer::pollFDForRefreshMessageCount = open(
+ myServer::pollForRefreshMessageCount.c_str(),
+ O_RDONLY | O_NONBLOCK)) < 0)
+ {
+ perror("Failed to open FIFO for reading");
+ exit(1);
+ }
+}
+
+void myServer::closePollForRefreshMessageCount()
+{
+ if(myServer::pollFDForRefreshMessageCount != -1)
+ {
+ // POSIX logic: close returns 0 on success thus true on fail...
+ if(close(myServer::pollFDForRefreshMessageCount))
+ perror("Failed to close message count update file "
+ "descriptor");
+ myServer::pollFDForRefreshMessageCount = -1;
+ }
+}
+
+void myServer::setCursesHierarchyPointerForRefreshing(CursesHierarchy* h)
+{
+ myServer::cursesHierarchyForRefreshing = h;
+}
diff -Nau -x Makefile.in -x Makefile -x .deps -x '*.cache' -x buildversion.H -x '*.log' -x config.status -r cone-beforechg/cone/myserver.H cone-0.96.2.20180216/cone/myserver.H
--- cone-beforechg/cone/myserver.H 2018-03-25 16:10:45.313386233 +0200
+++ cone-0.96.2.20180216/cone/myserver.H 2018-03-26 23:19:27.921753180 +0200
@@ -14,6 +14,7 @@
#include "curses/timer.H"
#include "myreadfolders.H"
#include "certificates.H"
+#include "curseshierarchy.H"
#include <string>
#include <vector>
@@ -86,6 +87,12 @@
std::map<std::string, std::map<std::string, std::string>
> folder_configuration;
+ // Allow refreshing message counts through messages on a named pipe.
+ // Necessary file descriptor, file name and GUI pointer.
+ static int pollFDForRefreshMessageCount;
+ static std::string pollForRefreshMessageCount;
+ static CursesHierarchy* cursesHierarchyForRefreshing;
+
public:
bool updateServerConfiguration(std::string name, std::string value);
std::string getServerConfiguration(std::string name);
@@ -220,11 +227,15 @@
void addHierarchy(bool assignRows);
void showHierarchy();
void updateHierarchy();
+
+ static void setPollForRefreshMessageCount(std::string fn);
+ static void closePollForRefreshMessageCount();
+ static void setCursesHierarchyPointerForRefreshing(CursesHierarchy* h);
private:
void addTopLevelFolders();
void addTopLevelFolder(std::string);
void disconnectTasks();
-
+ static void openPollFDForRefreshMessageCount();
public:
void alarm(); // Inherited from Timer
--=_masysma-3-1522101443-0000--
--=_masysma-3-7781-1522101443-0001
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEkKMBOo1F/f2B6jfK+Elw7bKeCLUFAlq5bMQACgkQ+Elw7bKe
CLUNeBAAlg7pj96S25B/6tqzx8mVFXKJgGAirBd+vius/zQLli58uEP2G7nJL3pD
zcGwLtVbBFjtzvzrEyinpGhIhG1rdRjlZ1E5gflN7Kv1ALVmuBQmr1wJVHZQ6hf6
T1hy8QAbwjzaombQHB4JHjg+8i/UFqmuD1lTSd5ZaNlb7UwXTGnLkFK75Wz7HJm6
Fl677qdmbyM+fO4nBCahSfJybhDx9oq+eAsJ/BDHwPrSX1LuHVzcuEL3crttH/4b
n2iqN+XddkTEfdCtbnXyo4XY1CYTwDQqsjQpIS58MsHOBjSnBMhsuOP6PGRxblg8
2oGoXzLuwfshLy+OutMKCJzIIzsKYnj4TsREj7dCLiBLJAKzq9vFfHo5GmzRFGFJ
JSvhxJCHZgRAnT5p2VcdWguZSkapG6MbPi+ohJrSqxAvvbGbslW3xr9yEYvpsrdV
X9fWaxsqfGr9A9uF3H5hw5ExfBKskePMmdxVL8adAvRuH+J9TbBPMhJ4O3Spfqag
ZZKWf7Qvtm7yTkluflg3og2BU0rA+MCoqtVc59RFB6w39w0+6ml3BoBIB+6XjLss
jFBVtQWEo67d1uL6d65IDYVG4xM+9rjSO1C/6HR4BmS483PNCJJU1ctJrpPPlhxD
pNaHZGRQX+4oBMjYXy8J6YIWnxtMyeouE3z5Lmo/sXNqY1eGEK0=
=ro9p
-----END PGP SIGNATURE-----
--=_masysma-3-7781-1522101443-0001--
--===============7516850857896640539==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
--===============7516850857896640539==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Courier-cone mailing list
[email protected]
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-cone
--===============7516850857896640539==--