Libtorrent Session_Status not updating - c++

Im trying to get Session_Status updated but for whatever reason the values of the structure never update, session is started like so:
using namespace libtorrent;
session* Session;
session_status* Session_Status;
session_settings* Session_Settings;
bool Start_Client_Sess ( )
{
using namespace libtorrent;
Session = new session;
Session_Status = new session_status;
Session_Settings = new session_settings;
Session->settings ( );
Session->set_settings ( *Session_Settings );
Session->add_extension ( create_ut_pex_plugin );
Session->add_extension ( create_ut_metadata_plugin );
Session->add_extension ( create_lt_trackers_plugin );
Session->add_extension ( create_smart_ban_plugin );
Session->start_upnp ( );
Session->start_natpmp ( );
Session->start_dht ( );
Session->start_lsd ( );
error_code e;
Session->listen_on ( std::make_pair ( 6881 , 6889 ) , e );
if ( e )
{
return false;
}
return true;
}
then on a Windows 1 second timer I'm doing this:
void RunTimer ( )
{
using namespace libtorrent;
Session->status ( );
if ( Session->is_listening ( ) )
{
if ( Session_Status->has_incoming_connections )
{
INT x = 2;
std::cout << x << "\n";
}
else
{
INT x = 1;
std::cout << x << "\n";
}
}
else
{
INT x = 0;
std::cout << x << "\n";
}
}
but no matter what the session is always listening even if the firewall is blocking Libtorrent and there is always connections even if the internet is off.

I believe you meant to assign the session status to your Session_Status object:
*Session_Status = Session->status();
I would suggest you don't heap allocate the session_status nor session_settings objects.

Related

Are utf-8 std::locales missing on iOS?

I'm trying to get std::locale that will be able to handle Russian symbols in my code.
std::optional< std::locale > TryGetLocale( const std::string& name )
{
try
{
std::locale res( name );
if( std::isalpha( L'ф', res ) )
return res;
else
return std::nullopt;
}
catch( ... )
{
return std::nullopt;
}
}
std::optional< std::locale > TryGenerateLocale( const std::string& name, const std::string base_name )
{
try
{
boost::locale::generator gen;
std::locale base( base_name );
auto res = std::locale( gen.generate( base, name ) );
if( std::isalpha( L'ф', res ) )
return res;
else
return std::nullopt;
}
catch( ... )
{
return std::nullopt;
}
}
std::locale TryGetLocale()
{
auto res = TryGetLocale( "ru_RU.utf8" );
if( !res )
res = TryGetLocale( "ru_RU.UTF-8" );
if( !res )
res = TryGenerateLocale( "ru_RU.UTF-8", "en_US.UTF-8" );
if( !res )
res = TryGenerateLocale( "ru_RU.UTF-8", "en_US.utf8" );
if( !res )
{
using namespace U_ICU_NAMESPACE;
int32_t count;
const Locale* list = Locale::getAvailableLocales( count );
for( size_t i = 0; i < static_cast< size_t >( count ); ++i )
{
res = TryGenerateLocale( "ru_RU.UTF-8", std::string( list[ i ].getName() ) + ".utf8" );
if( res )
break;
res = TryGenerateLocale( "ru_RU.UTF-8", std::string( list[ i ].getName() ) + ".UTF-8" );
if( res )
break;
}
}
if( !res )
{
std::terminate();
}
return *res;
}
On Android and desktops everything is ok. On iOS simulator everything is also ok, but when I try to launch this code on iOS device - I'm getting terminate, because I can't get any named std::locale. Is it normal behavior for iOS devices? Do they miss any UTF-8 c++ locales?

How to stop all pthreads when one has completed its work?

I'm trying to create a code to brute-force a random string but running it on one thread makes it take too long (as expected). I'm fiddling around with pthreads and this is what i've come up with:
void*
bruteForce ( void* ARGS )
{
args *arg = ( args * ) ARGS;
string STRING= arg->STRING;
string charSet = arg->charSet;
string guess = arg->guess;
char c;
int size;
int pos;
int lenght;
int j = 0;
char CHAR[STRING.length ( )];
size = charSet.length ( );
do
{
for ( j = 0; j < STRING.length ( ); j++ )
{
pos = rand ( ) % size;
CHAR[j] = charSet[pos];
guess = string ( CHAR );
//cout << guess[j];
}
//cout << guess << endl;
}
while ( STRING!= guess );
}
int
main ( int argc, char** argv )
{
srand ( ( unsigned ) ( time ( NULL ) ) );
const int NUMBER_OF_THREADS = 10;
args arg;
ifstream myFile;
string STRING;
string charSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
string guess;
pthread_t threads[NUMBER_OF_THREADS];
void* status;
arg.charSet = charSet;
arg.STRING= STRING;
char c;
int size;
int pos;
int lenght;
int j = 0;
myFile.open ( "string.txt" );
getline ( myFile, STRING);
size = charSet.length ( );
int rc;
//Creating threads for cracking the string
for ( int i = 0; i < NUMBER_OF_THREADS; i++ )
{
rc = pthread_create ( &threads[i], NULL, bruteForce, ( void* ) &arg );
if ( rc )
{
cout << "Couldnt create thread";
exit ( 1 );
}
}
//Joining threads
for ( int i = 0; i < NUMBER_OF_THREADS; i++ )
{
rc = pthread_join ( threads[i], &status );
if ( rc )
{
cout << "thread number " << i << " was unable to join: " << rc << endl;
exit ( 1 );
}
}
}
Now, I need someway of signaling that one of the threads has already guessed the string correctly and terminate the others. I read some of the documentation for pthread library and couldn't find anything. Any help is appreciated.
PS: I know the brute-force algorithm is by far not the best.
As long as you don't want your program to run any longer after the answer is found, you can just call exit(0) from the thread which found the answer.
do
{
// ...
}
while ( STRING!= guess );
std::cout << guess << std::endl;
std::exit(0);
Clumsy but workable in your case:
Add a DONE flag in global scope. Set it when a result is found by any thread.
Make each thread's loop be dependent on the flag.
bool DONE=false; // set to true to stop other threads
void*bruteForce ( void* ARGS )
{ ...
do
{ <try a string>
}
while ( !DONE && STRING!= guess );
DONE=true; // set redundantly but that doesn't hurt
}
Your main program can still do the join to collect finished pthreads, and then continue on with any work it might want to do on the guessed answer.

Reading a config file

I'm trying to read a config file like this:
rawfile=input.raw
encfile=encoded.enc
decfile=decoded.raw
width=512
height=512
rle=1
quantfile=matrix.txt
logfile=log.txt
Having this function:
void Compression::readConfigFile(char * input)
{
string lineBuf;
string optionBuf;
std::ifstream confFile(input);
if ( confFile.is_open() )
{
while ( getline( confFile, lineBuf ) )
{
optionBuf = "rawfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->rawfile = lineBuf.c_str();
}
optionBuf = "encfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->encfile = lineBuf.c_str();
}
optionBuf = "decfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->encfile = lineBuf.c_str();
}
optionBuf = "width=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->width = atoi( lineBuf.c_str() );
}
optionBuf = "height=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->height = atoi( lineBuf.c_str() );
}
optionBuf = "rle=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->rle = atoi( lineBuf.c_str() );
}
optionBuf = "quantfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length());
this->matrix = lineBuf.c_str();
}
optionBuf = "logfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->logfile = lineBuf.c_str();
}
confFile.close();
}
}
else
cout << "Can't open file: " << input << endl;
}
But it doesn't work. My ints are 0 or some big number. My strings are still empty.
Can someone help me please?
Kind regards,
shouldn't you rather close the file outside of the while loop ?
while() {
...
}
confFile.close();

C++ Logger Runtime Threshold

namespace Log {
#include <ctime>
#include <string>
#include <boost\scoped_ptr.hpp>
#ifndef LOG_PREPEND_TIMESTAMP_DEFAULT
#define LOG_PREPEND_TIMESTAMP_DEFAULT false
#endif
enum LogLevel_t { logFatal = 0, logError = 1, logWarning = 2, logVerbose = 3, logDebug = 4 };
std::string LogLevelToString( const LogLevel_t level ) {
static const char* const buffer[] = { "Fatal", "Error", "Warning", "Verbose", "Debug" };
return buffer[level];
}
class Log: public boost::noncopyable {
protected:
boost::scoped_ptr< std::ostringstream > Output_String;
bool m_Prepending_Timestamp;
size_t m_LinesOutputted;
public:
Log():
Output_String( new std::ostringstream ),
m_Prepending_Timestamp( LOG_PREPEND_TIMESTAMP_DEFAULT ),
m_LinesOutputted( 0 ) {}
void UsingTimestamp( bool Prepending_Timestamp = true ) {
m_Prepending_Timestamp = Prepending_Timestamp;
}
std::ostringstream& Get( const LogLevel_t level ) {
// Write line number
++m_LinesOutputted;
*Output_String << m_LinesOutputted << " | ";
if( m_Prepending_Timestamp == true ) {
//prepare a timestamp
time_t now = time( NULL );
std::string formatted_time( asctime( localtime( &now ) ) ); /* &now can be replaced with the above call when r-value references work (maybe) saving a stack var */
formatted_time.erase(( formatted_time.length( ) - 1 ), 1 ); /* Removes the \n(newline) that asctime adds for better formatting */
// Write timestamp to stream
*Output_String << formatted_time << " || ";
}
// Write Logging level(severity) to stream
*Output_String << LogLevelToString( level ) << " || ";
return *Output_String;
}
void Flush() {
*Output_String << std::endl;
fprintf( stdout, "%s", Output_String->str( ).c_str( ) );
fflush( stdout );
Output_String.reset( new std::ostringstream ); /* streams have lots of internal state clean streams are good */
}
~Log() {
*Output_String << std::endl;
fprintf( stdout, "%s", Output_String->str( ).c_str( ) );
fflush( stdout );
}
};
How would I implement a threshold without a macro?
If I wrap the body of get with a check I still have to return the stringstream.
I could change the return type to a pointer instead of a reference then return NULL but then every logger statement would have to have a null check for the returned stringstream

How to use MySQL Embedded in a multithreaded environment?

I am writing a program that uses MySQLe as embedded backend. The database library is owned by an object called "Domain". This Domain object runs within the main thread.
The program launches another thread running a XML-RPC server (boost::thread and xmlrpc_c::serverAbyss). It is linked to the Domain object.
When the XML-RPC server makes the Domain object execute an SQL query the program crashes:
Program received signal: “EXC_BAD_ACCESS”.
[Switching to process 73191]
[Switching to process 73191]
Xcode could not locate source file: regex.cpp (line: 74)
When the master thread calls Domain object's method that executes SQL queries the program still runs.
/*
* Ports listening
*
* - create a Rpc_Server object
* - create a dedicated thread
*/
Rpc_Server server(&domain, &conf_params, &router);
boost::thread server_thread(boost::bind(&Rpc_Server::run, &server)); // This thread makes the server crash
/*
* Domain routine
*
* - Check for ready jobs every minute
*/
while (1) {
v_jobs jobs = domain.get_ready_jobs(conf_params.get_param("node_name")); // This method does NOT make the server crash
sleep(60);
}
Both the Domain object's methods and the Database object's methods lock a mutex to avoid multi access.
bool Mysql::execute(const std::string* query) {
MYSQL_RES* res;
MYSQL_ROW row;
if ( query == NULL )
return false;
this->updates_mutex.lock();
std::cout << query->c_str() << std::endl;
if ( mysql_query(this->mysql, query->c_str()) != 0 ) {
std::cerr << query << std::endl << mysql_error(this->mysql);
UNLOCK_MUTEX;
return false;
}
res = mysql_store_result(this->mysql);
if (res)
while ( ( row = mysql_fetch_row(res) ) )
for ( uint i=0 ; i < mysql_num_fields(res) ; i++ )
std::cout << row[i] << std::endl;
else
if ( mysql_field_count(this->mysql) != 0 ) {
std::cerr << "Erreur : " << mysql_error(this->mysql) << std::endl;
mysql_free_result(res);
this->updates_mutex.unlock();
return false;
}
mysql_free_result(res);
this->updates_mutex.unlock();
return true;
}
bool Domain::add_node(const std::string* running_node, const std::string* n, const int* w) {
std::string query;
this->updates_mutex.lock();
query = "START TRANSACTION;";
if ( this->database.execute(&query) == false ) {
this->updates_mutex.unlock();
return false;
}
query = "REPLACE INTO node (node_name,node_weight) VALUES ('";
query += n->c_str();
query += "','";
query += boost::lexical_cast<std::string>(*w);
query += "');";
if ( this->database.execute(&query) == false ) {
query = "ROLLBACK;";
this->database.execute(&query);
this->updates_mutex.unlock();
return false;
}
query = "COMMIT;"
if ( this->database.execute(&query) == false ) {
this->updates_mutex.unlock();
return false;
} else
this->updates_mutex.unlock();
return true;
}
The MySQLe is created there:
bool Mysql::prepare(const std::string* node_name, const std::string* db_skeleton) {
static char* server_args[] = {"this_program","--datadir=."};
static char* server_groups[] = {"embedded","server","this_program_SERVER",(char *)NULL};
std::string query("CREATE DATABASE IF NOT EXISTS ");
// DB init
if ( mysql_library_init(sizeof(server_args) / sizeof(char *), server_args, server_groups) )
std::cerr << "could not initialize MySQL library" << std::endl;
std::cout << "mysql init..." << std::endl;
if ( (this->mysql = mysql_init(NULL)) == NULL )
std::cerr << mysql_error(this->mysql) << std::endl;
if ( ! mysql_thread_safe() ) {
std::cerr << "MySQL is NOT theadsafe !" << std::endl;
return false;
}
mysql_options(this->mysql, MYSQL_READ_DEFAULT_GROUP, "embedded");
mysql_options(this->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
mysql_real_connect(this->mysql, NULL, NULL, NULL, NULL, 0, NULL, 0);
// Creates the schema
query += this->translate_into_db(node_name);
query += ";";
if ( this->execute(&query) == false )
return false;
// Creates the schema
query = "CREATE SCHEMA IF NOT EXISTS ";
query += this->translate_into_db(node_name);
query += " DEFAULT CHARACTER SET latin1;";
this->execute(&query);
// Uses it
query = "USE " + this->translate_into_db(node_name) + ";";
this->execute(&query);
// Loads the skeleton from file
return this->load_file(db_skeleton->c_str());
}
Am I wrong somewhere?
Do you have an example to show me?
I found the solution to my problem. Each thread needs to initialize the MySQL environment. That is to say execute some mysql_* functions.
Here are the modified / new methods :
bool Mysql::atomic_execute(const std::string* query) {
MYSQL_RES* res;
MYSQL_ROW row;
boost::regex empty_string("^\\s+$", boost::regex::perl);
if ( query == NULL )
return false;
if ( query->empty() == true or boost::regex_match(*query, empty_string) == true ) {
std::cerr << "Error : query is empty !" << std::endl;
return false;
}
this->updates_mutex.lock();
if ( mysql_query(this->mysql, query->c_str()) != 0 ) {
std::cerr << query << std::endl << mysql_error(this->mysql);
this->updates_mutex.unlock();;
return false;
}
res = mysql_store_result(this->mysql);
if (res)
while ( ( row = mysql_fetch_row(res) ) )
for ( uint i=0 ; i < mysql_num_fields(res) ; i++ )
std::cout << row[i] << std::endl;
else
if ( mysql_field_count(this->mysql) != 0 ) {
std::cerr << "Erreur : " << mysql_error(this->mysql) << std::endl;
mysql_free_result(res);
this->updates_mutex.unlock();
return false;
}
mysql_free_result(res);
this->updates_mutex.unlock();
return true;
}
bool Mysql::standalone_execute(const v_queries* queries) {
MYSQL* local_mysql = this->init();
std::string query = "START TRANSACTION;";
if ( this->atomic_execute(&query) == false ) {
mysql_close(local_mysql);
return false;
}
BOOST_FOREACH(std::string q, *queries) {
std::cout << q.c_str() << std::endl;
if ( this->atomic_execute(&q) == false ) {
query = "ROLLBACK";
this->atomic_execute(&query);
mysql_close(local_mysql);
return false;
}
}
query = "COMMIT";
if ( this->atomic_execute(&query) == false ) {
mysql_close(local_mysql);
return false;
}
mysql_close(local_mysql);
return true;
}
MYSQL* Mysql::init() {
MYSQL* local_mysql;
local_mysql = mysql_init(this->mysql);
mysql_options(this->mysql, MYSQL_READ_DEFAULT_GROUP, "embedded");
mysql_options(this->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
mysql_real_connect(local_mysql, NULL, NULL, NULL, NULL, 0, NULL, 0);
return local_mysql;
}
The atomic_execute method is used to send single queries to the server.
The standalone_execute method initializes a connection and a transaction, then it sends the whole queries to the server using atomic_execute.
I do not know if a ROLLBACK is useful in case of COMMIT's failure...
The code might need some improvements but it works.