I would like to implement a constructor for a Javascript Object in C++, using SpiderMonkey 38's API. But a constructor needs access to this (the JS Object being constructed) and the docs for JS::CallArgs say you mustn't call thisv() from a constructor, without suggesting any alternative. Does that mean it isn't actually possible to write a useful constructor in C++?
In C++ you just have to create the object that should be returned from the constructor yourself. (Nothing creates an initial object that would be accessible from this for your) Depending on what you need you should look into creating a new JSClass for that object.
bool
MyConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JS::RootedObject obj(cx, JS_NewObject(cx, MyJSClass));
if (!obj)
return false;
args.rval().setObject(*obj);
return true;
}
I'm trying to get my head around async but have not yet found a way to pass pointers. The aim is to pass a pointer to a pointer so that the thread readTable initialises the pointer to a PostgreSQL connection as shown below.
PGconn *conn = NULL;
future<int> resultFuture;
void init
{
resultFuture = async(launch::async, readTable(&conn));
}
However the compiler complains with:
error: no matching function for call to ‘async(std::launch, int)'
Is passing pointers like this not allowed with async?
Thanks for any help.
I guess
void init
{
resultFuture = async(launch::async, readTable,&conn);
}
the second parameters is a Callable (which is a function to pointer, or an object with overloaded operator() or a lambda function). all the rest are the argument to pass into the callable.
please read std::async documentation here:
http://en.cppreference.com/w/cpp/thread/async
and about perfect forwarding here :
Advantages of using forward
I'm new to D and I'm writing a simple multithreaded server for practice. A common paradigm for starting client handler threads in C is to pass the file descriptor of the newly-accept()ed socket into pthread_create(), but D's std.concurrency.spawn() will not allow me to pass the Socket because it's mutable and accessible by two threads.
Of course, I don't actually want an immutable socket (which is why I don't really want to cast it in the main thread unless I have to) - I want to pass a mutable one in and have it go out of scope in the main thread. How would I go about this? Should(/can) I use tid.send(s) to let the thread use the socket? For some reason that seems very clunky to me.
My code now:
void main() {
Socket listener = new TcpSocket;
...
for (;;) {
Socket s = listener.accept();
scope(exit) s.close();
auto tid = spawn(&clientHandler, s);
}
}
void clientHandler(Socket s) {
...
}
Which produces: Error: static assert "Aliases to mutable thread-local data not allowed." ... instantiated from here: spawn!(Socket)
you need to cast the socket to shared and back again in the clienthandler
auto tid = spawn(&clientHandler, cast(shared) s);
void clientHandler(shared Socket s) {
Socket sock = cast(Socket)s;
scope(exit)sock.close();
}
the reason for this is that all local variables are implicitly thread local unless specified shared, and only references to shared or immutable can be passed as argument to spawn (or send) while stuff passed by value (structs without references and primitives) is fine
also you should put the close int the handler as with your current implementation the socket will likely be closed before the newly spawned thread has a chance to run
The problem here isn't the socket, which is a local variable. It's the clientHandler, whose declaration you haven't shown, but clearly it is thread-local as it says in the error message, when there should be a new one per accepted socket. The hint is the word 'alias', which refers to the & operator.
I am overloading "malloc" by pre-loading a library. In this custom "malloc", i am using environment variable to distinguish my program to use my custom "malloc" from the general "malloc".
The problem is that, after several "mallocs" the program gets stuck inside getenv() call. I am not able to figure out why the program is getting stuck inside it.
The code is the following:
void* PerfTrackMallocInterposition::Malloc(size_t size) {
// Malloc with statistics
pthread_mutex_lock(&fgPTMutex);
char *checkCDBEnd=NULL;
static const char* CDBEndEnv = "checkCDBEnd";
checkCDBEnd = getenv(CDBEndEnv); //program gets stuck here
if(checkCDBEnd!=NULL)
{
if(checkCDBEnd[0]=='1')
{
if(size>1024)
{
void *result = Alloc(size); //Call to custom malloc
pthread_mutex_unlock(&fgPTMutex);
return result;
}
}
}
void* result = (*fPMalloc)(size); //call to normal malloc
pthread_mutex_unlock(&fgPTMutex);
return result;
}
I also get a bus error at same position while using this library with vim editor.
Please help me.
Thank You
Are you sure the program gets stuck on the getenv() call? I would be more suspicious of the mutexes: pthread_mutex_lock(&fgPTMutex); will block if another thread holds the mutex
I'm learning Boost::asio and all that async stuff. How can I asynchronously read to variable user_ of type std::string? Boost::asio::buffer(user_) works only with async_write(), but not with async_read(). It works with vector, so what is the reason for it not to work with string? Is there another way to do that besides declaring char user_[max_len] and using Boost::asio::buffer(user_, max_len)?
Also, what's the point of inheriting from boost::enable_shared_from_this<Connection> and using shared_from_this() instead of this in async_read() and async_write()? I've seen that a lot in the examples.
Here is a part of my code:
class Connection
{
public:
Connection(tcp::acceptor &acceptor) :
acceptor_(acceptor),
socket_(acceptor.get_io_service(), tcp::v4())
{ }
void start()
{
acceptor_.get_io_service().post(
boost::bind(&Connection::start_accept, this));
}
private:
void start_accept()
{
acceptor_.async_accept(socket_,
boost::bind(&Connection::handle_accept, this,
placeholders::error));
}
void handle_accept(const boost::system::error_code& err)
{
if (err)
{
disconnect();
}
else
{
async_read(socket_, boost::asio::buffer(user_),
boost::bind(&Connection::handle_user_read, this,
placeholders::error, placeholders::bytes_transferred));
}
}
void handle_user_read(const boost::system::error_code& err,
std::size_t bytes_transferred)
{
if (err)
{
disconnect();
}
else
{
...
}
}
...
void disconnect()
{
socket_.shutdown(tcp::socket::shutdown_both);
socket_.close();
socket_.open(tcp::v4());
start_accept();
}
tcp::acceptor &acceptor_;
tcp::socket socket_;
std::string user_;
std::string pass_;
...
};
The Boost.Asio documentation states:
A buffer object represents a contiguous region of memory as a 2-tuple consisting of a pointer and size in bytes. A tuple of the form {void*, size_t} specifies a mutable (modifiable) region of memory.
This means that in order for a call to async_read to write data to a buffer, it must be (in the underlying buffer object) a contiguous block of memory. Additionally, the buffer object must be able to write to that block of memory.
std::string does not allow arbitrary writes into its buffer, so async_read cannot write chunks of memory into a string's buffer (note that std::string does give the caller read-only access to the underlying buffer via the data() method, which guarantees that the returned pointer will be valid until the next call to a non-const member function. For this reason, Asio can easily create a const_buffer wrapping an std::string, and you can use it with async_write).
The Asio documentation has example code for a simple "chat" program (see http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/examples.html#boost_asio.examples.chat) that has a good method of overcoming this problem. Basically, you need to have the sending TCP send along the size of a message first, in a "header" of sorts, and your read handler must interpret the header to allocate a buffer of a fixed size suitable for reading the actual data.
As far as the need for using shared_from_this() in async_read and async_write, the reason is that it guarantees that the method wrapped by boost::bind will always refer to a live object. Consider the following situation:
Your handle_accept method calls async_read and sends a handler "into the reactor" - basically you've asked the io_service to invoke Connection::handle_user_read when it finishes reading data from the socket. The io_service stores this functor and continues its loop, waiting for the asynchronous read operation to complete.
After your call to async_read, the Connection object is deallocated for some reason (program termination, an error condition, etc.)
Suppose the io_service now determines that the asynchronous read is complete, after the Connection object has been deallocated but before the io_service is destroyed (this can occur, for example, if io_service::run is running in a separate thread, as is typical). Now, the io_service attempts to invoke the handler, and it has an invalid reference to a Connection object.
The solution is to allocate Connection via a shared_ptr and use shared_from_this() instead of this when sending a handler "into the reactor" - this allows io_service to store a shared reference to the object, and shared_ptr guarantees that it won't be deallocated until the last reference expires.
So, your code should probably look something like:
class Connection : public boost::enable_shared_from_this<Connection>
{
public:
Connection(tcp::acceptor &acceptor) :
acceptor_(acceptor),
socket_(acceptor.get_io_service(), tcp::v4())
{ }
void start()
{
acceptor_.get_io_service().post(
boost::bind(&Connection::start_accept, shared_from_this()));
}
private:
void start_accept()
{
acceptor_.async_accept(socket_,
boost::bind(&Connection::handle_accept, shared_from_this(),
placeholders::error));
}
void handle_accept(const boost::system::error_code& err)
{
if (err)
{
disconnect();
}
else
{
async_read(socket_, boost::asio::buffer(user_),
boost::bind(&Connection::handle_user_read, shared_from_this(),
placeholders::error, placeholders::bytes_transferred));
}
}
//...
};
Note that you now must make sure that each Connection object is allocated via a shared_ptr, e.g.:
boost::shared_ptr<Connection> new_conn(new Connection(...));
Hope this helps!
This isn't intended to be an answer per se, but just a lengthy comment: a very simple way to convert from an ASIO buffer to a string is to stream from it:
asio::streambuf buff;
asio::read_until(source, buff, '\r'); // for example
istream is(&buff);
is >> targetstring;
This is a data copy, of course, but that's what you need to do if you want it in a string.
You can use a std:string with async\_read() like this:
async_read(socket_, boost::asio::buffer(&user_[0], user_.size()),
boost::bind(&Connection::handle_user_read, this,
placeholders::error, placeholders::bytes_transferred));
However, you'd better make sure that the std::string is big enough to accept the packet that you're expecting and padded with zeros before calling async\_read().
And as for why you should NEVER bind a member function callback to a this pointer if the object can be deleted, a more complete description and a more robust method can be found here: Boost async_* functions and shared_ptr's.
Boost Asio has two styles of buffers. There's boost::asio::buffer(your_data_structure), which cannot grow, and is therefore generally useless for unknown input, and there's boost::asio::streambuf which can grow.
Given a boost::asio::streambuf buf, you turn it into a string with std::string(std::istreambuf_iterator<char>(&buf), {});.
This is not efficient as you end up copying data once more, but that would require making boost::asio::buffer aware of growable containers, i.e. containers that have a .resize(N) method. You can't make it efficient without touching Boost code.