summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlouis <louis.braun@gmx.de>2014-10-25 05:55:19 +0200
committerlouis <louis.braun@gmx.de>2014-10-25 05:55:19 +0200
commitf2167b1467eb98325f64300f96318391077c688b (patch)
tree9b45adaa03f116be291449dee03eaca3faac959a
parent74969a32d8604b15c07a755cc787b6a304868607 (diff)
downloadvdr-plugin-scraper2vdr-f2167b1467eb98325f64300f96318391077c688b.tar.gz
vdr-plugin-scraper2vdr-f2167b1467eb98325f64300f96318391077c688b.tar.bz2
Version 0.1.5 - introduced new DB API
-rw-r--r--HISTORY3
-rw-r--r--lib/common.h143
-rw-r--r--lib/config.h2
-rw-r--r--lib/db.c1
-rw-r--r--lib/db.h94
-rw-r--r--lib/demo.c2
-rw-r--r--lib/tabledef.c6
-rw-r--r--lib/tabledef.h6
-rw-r--r--lib/test.c2
-rw-r--r--scraper2vdr.c5
-rw-r--r--scraper2vdr.h2
-rw-r--r--scrapmanager.c4
-rw-r--r--update.c3
13 files changed, 236 insertions, 37 deletions
diff --git a/HISTORY b/HISTORY
index 016de5a..183bd2b 100644
--- a/HISTORY
+++ b/HISTORY
@@ -33,3 +33,6 @@ Version 0.1.3
Version 0.1.4
- added ScraperGetPosterBannerV2 Service
+
+Versionn 0.1.5
+- introduced new DB API
diff --git a/lib/common.h b/lib/common.h
index 5aa4819..e757e3d 100644
--- a/lib/common.h
+++ b/lib/common.h
@@ -11,6 +11,7 @@
#include <stdint.h> // uint_64_t
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <string>
#include <openssl/md5.h> // MD5_*
@@ -281,4 +282,146 @@ class LogDuration
};
//***************************************************************************
+// Semaphore
+//***************************************************************************
+
+#include <sys/sem.h>
+
+class Sem
+{
+ public:
+
+ Sem(key_t aKey)
+ {
+ locked = no;
+ key = aKey;
+
+ if ((id = semget(key, 1, 0666 | IPC_CREAT)) == -1)
+ tell(0, "Error: Can't get semaphore, errno (%d) '%s'",
+ errno, strerror(errno));
+ }
+
+ ~Sem()
+ {
+ if (locked)
+ v();
+ }
+
+ // ----------------------
+ // get lock
+
+ int p()
+ {
+ sembuf sops[2];
+
+ sops[0].sem_num = 0;
+ sops[0].sem_op = 0; // wait for lock
+ sops[0].sem_flg = SEM_UNDO;
+
+ sops[1].sem_num = 0;
+ sops[1].sem_op = 1; // increment
+ sops[1].sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, sops, 2) == -1)
+ {
+ tell(0, "Error: Can't lock semaphore, errno (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ locked = yes;
+
+ return success;
+ }
+
+ // ----------------------
+ // increment
+
+ int inc()
+ {
+ sembuf sops[1];
+
+ sops[0].sem_num = 0;
+ sops[0].sem_op = 1; // increment
+ sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, sops, 1) == -1)
+ {
+ if (errno != EAGAIN)
+ tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ locked = yes;
+
+ return success;
+ }
+
+ // ----------------------
+ // decrement
+
+ int dec()
+ {
+ return v();
+ }
+
+ // ----------------------
+ // check
+
+ int check()
+ {
+ sembuf sops[1];
+
+ sops[0].sem_num = 0;
+ sops[0].sem_op = 0;
+ sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, sops, 1) == -1)
+ {
+ if (errno != EAGAIN)
+ tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ return success;
+ }
+
+ // ----------------------
+ // release lock
+
+ int v()
+ {
+ sembuf sops;
+
+ sops.sem_num = 0;
+ sops.sem_op = -1; // release control
+ sops.sem_flg = SEM_UNDO | IPC_NOWAIT;
+
+ if (semop(id, &sops, 1) == -1)
+ {
+ if (errno != EAGAIN)
+ tell(0, "Error: Can't unlock semaphore, errno (%d) '%s'",
+ errno, strerror(errno));
+
+ return fail;
+ }
+
+ locked = no;
+
+ return success;
+ }
+
+ private:
+
+ key_t key;
+ int id;
+ int locked;
+};
+
+//***************************************************************************
#endif //___COMMON_H
diff --git a/lib/config.h b/lib/config.h
index 4389c58..f32877a 100644
--- a/lib/config.h
+++ b/lib/config.h
@@ -11,6 +11,8 @@
#include "common.h"
+#define EPG_PLUGIN_SEM_KEY 0x3db00001
+
//***************************************************************************
// Config
//***************************************************************************
diff --git a/lib/db.c b/lib/db.c
index 6ee2c71..d08a82d 100644
--- a/lib/db.c
+++ b/lib/db.c
@@ -512,6 +512,7 @@ int cDbConnection::dbPort = 3306;
char* cDbConnection::dbUser = 0;
char* cDbConnection::dbPass = 0;
char* cDbConnection::dbName = 0;
+Sem* cDbConnection::sem = 0;
//***************************************************************************
// Object
diff --git a/lib/db.h b/lib/db.h
index 5f44c14..4c3bc08 100644
--- a/lib/db.h
+++ b/lib/db.h
@@ -8,11 +8,15 @@
#ifndef __DB_H
#define __DB_H
+#include <linux/unistd.h>
+
+#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
+
#include <mysql/mysql.h>
#include <list>
@@ -550,13 +554,11 @@ class cDbConnection
virtual ~cDbConnection()
{
- if (mysql)
- {
- mysql_close(mysql);
- mysql_thread_end();
- }
+ close();
}
+ int isConnected() { return getMySql() > 0; }
+
int attachConnection()
{
static int first = yes;
@@ -565,14 +567,16 @@ class cDbConnection
{
connectDropped = yes;
+ tell(0, "Calling mysql_init(%ld)", syscall(__NR_gettid));
+
if (!(mysql = mysql_init(0)))
return errorSql(this, "attachConnection(init)");
if (!mysql_real_connect(mysql, dbHost,
dbUser, dbPass, dbName, dbPort, 0, 0))
{
- mysql_close(mysql);
- mysql = 0;
+ close();
+
tell(0, "Error, connecting to database at '%s' on port (%d) failed",
dbHost, dbPort);
@@ -601,19 +605,25 @@ class cDbConnection
return success;
}
- void detachConnection()
- {
- attached--;
-
- if (!attached)
+ void close()
+ {
+ if (mysql)
{
+ tell(0, "Closing mysql connection and calling mysql_thread_end(%ld)", syscall(__NR_gettid));
+
mysql_close(mysql);
mysql_thread_end();
mysql = 0;
}
}
- int isConnected() { return getMySql() > 0; }
+ void detachConnection()
+ {
+ attached--;
+
+ if (!attached)
+ close();
+ }
int check()
{
@@ -724,12 +734,7 @@ class cDbConnection
MYSQL* getMySql()
{
if (connectDropped && mysql)
- {
- mysql_close(mysql);
- mysql_thread_end();
- mysql = 0;
- attached = 0;
- }
+ close();
return mysql;
}
@@ -756,22 +761,59 @@ class cDbConnection
int errorSql(cDbConnection* mysql, const char* prefix, MYSQL_STMT* stmt = 0, const char* stmtTxt = 0);
- void showStat(const char* name = "") { statements.showStat(name); }
+ void showStat(const char* name = "") { statements.showStat(name); }
+
+ // -----------------------------------------------------------
+ // init() and exit() must exactly called 'once' per process
- static int init()
+ static int init(key_t semKey)
{
- if (mysql_library_init(0, 0, 0))
+ if (semKey && !sem)
+ sem = new Sem(semKey);
+
+ if (!sem || sem->check() == success)
+ {
+ // call only once per process
+
+ if (sem)
+ tell(1, "Info: Calling mysql_library_init()");
+
+ if (mysql_library_init(0, 0, 0))
+ {
+ tell(0, "Error: mysql_library_init() failed");
+ return fail;
+ }
+ }
+ else if (sem)
{
- tell(0, "Error: mysql_library_init failed");
- return fail; // return errorSql(0, "init(library_init)");
+ tell(1, "Info: Skipping calling mysql_library_init(), it's already done!");
}
+ if (sem)
+ sem->inc(); // count usage per process
+
return success;
}
static int exit()
{
- mysql_library_end();
+ mysql_thread_end();
+
+ if (sem)
+ sem->dec();
+
+ if (!sem || sem->check() == success)
+ {
+ if (sem)
+ tell(1, "Info: Released the last usage of mysql_lib, calling mysql_library_end() now");
+
+ mysql_library_end();
+ }
+ else if (sem)
+ {
+ tell(1, "Info: The mysql_lib is still in use, skipping mysql_library_end() call");
+ }
+
free(dbHost);
free(dbUser);
free(dbPass);
@@ -792,6 +834,8 @@ class cDbConnection
int inTact;
int connectDropped;
+ static Sem* sem;
+
static char* encoding;
// connecting data
diff --git a/lib/demo.c b/lib/demo.c
index 1d6ee10..b8a6592 100644
--- a/lib/demo.c
+++ b/lib/demo.c
@@ -15,7 +15,7 @@ const char* logPrefix = "demo";
void initConnection()
{
- cDbConnection::init();
+ cDbConnection::init(0x3db00012);
cDbConnection::setEncoding("utf8");
cDbConnection::setHost("localhost");
diff --git a/lib/tabledef.c b/lib/tabledef.c
index d9826f5..3ea28c1 100644
--- a/lib/tabledef.c
+++ b/lib/tabledef.c
@@ -117,9 +117,9 @@ cDbService::FieldDef cTableEvents::fields[] =
// episodes (constable)
- { "episode", ffAscii, 250, fiEpisode, ftData },
- { "episodepart", ffAscii, 250, fiEpisodePart, ftData },
- { "episodelang", ffAscii, 3, fiEpisodeLang, ftData },
+// { "episodecompname", ffAscii, 250, fiEpisode, ftData },
+// { "episodecomppartname", ffAscii, 250, fiEpisodePart, ftData },
+// { "episodelang", ffAscii, 3, fiEpisodeLang, ftData },
// tv scraper
diff --git a/lib/tabledef.h b/lib/tabledef.h
index 9936f4e..9e6e83d 100644
--- a/lib/tabledef.h
+++ b/lib/tabledef.h
@@ -251,9 +251,9 @@ class cTableEvents : public cDbTable
fiExtEpNum,
fiImageCount,
- fiEpisode,
- fiEpisodePart,
- fiEpisodeLang,
+// fiEpisode,
+// fiEpisodePart,
+// fiEpisodeLang,
fiScrSeriesId,
fiScrSeriesEpisode,
diff --git a/lib/test.c b/lib/test.c
index fa85c70..e514aae 100644
--- a/lib/test.c
+++ b/lib/test.c
@@ -21,7 +21,7 @@ const char* logPrefix = "test";
void initConnection()
{
- cDbConnection::init();
+ cDbConnection::init(0x3db00011);
cDbConnection::setEncoding("utf8");
cDbConnection::setHost("localhost");
diff --git a/scraper2vdr.c b/scraper2vdr.c
index 8f81c50..e21d234 100644
--- a/scraper2vdr.c
+++ b/scraper2vdr.c
@@ -6,7 +6,10 @@
* $Id$
*/
+#include "lib/config.h"
+
#include "scraper2vdr.h"
+
const char* logPrefix = LOG_PREFIX;
#if defined (APIVERSNUM) && (APIVERSNUM < 10600)
@@ -80,7 +83,7 @@ eOSState cScraper2VdrPluginMenu::ProcessKey(eKeys key) {
//***************************************************************************
cPluginScraper2vdr::cPluginScraper2vdr(void) {
- cDbConnection::init();
+ cDbConnection::init(EPG_PLUGIN_SEM_KEY);
}
cPluginScraper2vdr::~cPluginScraper2vdr() {
diff --git a/scraper2vdr.h b/scraper2vdr.h
index 7346edf..30c63cd 100644
--- a/scraper2vdr.h
+++ b/scraper2vdr.h
@@ -13,7 +13,7 @@
//***************************************************************************
// Constants
//***************************************************************************
-static const char *VERSION = "0.1.4";
+static const char *VERSION = "0.1.5";
static const char *DESCRIPTION = "'scraper2vdr' plugin";
static const char *MAINMENUENTRY = "Scraper2Vdr";
diff --git a/scrapmanager.c b/scrapmanager.c
index 4b07ff3..2df3c65 100644
--- a/scrapmanager.c
+++ b/scrapmanager.c
@@ -354,7 +354,7 @@ void cScrapManager::DumpMovies(void) {
}
void cScrapManager::DumpRecordings(void) {
- tell(0, "%d recordings in memory:", recordings.size());
+ tell(0, "%ld recordings in memory:", recordings.size());
for (map<sRecordingsKey, sEventsValue>::iterator it = recordings.begin(); it != recordings.end(); it++) {
sRecordingsKey key = it->first;
sEventsValue val = it->second;
@@ -481,6 +481,7 @@ bool cScrapManager::GetMovie(cMovie *m) {
bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
sEventsValue v;
+ v.episodeId = 0;
if (call->event) {
sEventsKey k;
k.eventId = call->event->EventID();
@@ -516,6 +517,7 @@ bool cScrapManager::GetPosterBanner(ScraperGetPosterBanner *call) {
bool cScrapManager::GetPosterBannerV2(ScraperGetPosterBannerV2 *call) {
sEventsValue v;
+ v.episodeId = 0;
if (call->event) {
sEventsKey k;
k.eventId = call->event->EventID();
diff --git a/update.c b/update.c
index 09b27b1..9fdc358 100644
--- a/update.c
+++ b/update.c
@@ -77,7 +77,6 @@ cUpdate::cUpdate(cScrapManager *manager) : cThread("update thread started", true
cUpdate::~cUpdate() {
if (loopActive)
Stop();
- exitDb();
}
// global field definitions
@@ -1356,6 +1355,8 @@ void cUpdate::Action()
worked = no;
}
+
+ exitDb(); // don't call exit in dtor, outside from thread!!
loopActive = no;
tell(0, "Update thread ended (pid=%d)", getpid());
}