javascript:for (var b=document.getElementsByTagName("*"), n = 0; n < b.length; n++) { if (b[n].getAttribute("g:type") == "plusone" && b[n].getAttribute("aria-pressed") != "true") b[n].click() }
2011/06/30
Google+でとりあえず全部+1押しちゃうブックマークレット書いた。
2011/06/28
gthreads が有効になっていない mingw で gthreads する
ダウンロード配布物となっている mingw の c++config.h では
lambda使えばこんなのも出来て、たのしーーーー!
/* Define if gthreads library is available. */
/* #undef _GLIBCXX_HAS_GTHREADS */
となっていて、下記の様なthreadを使ったコードはコンパイル出来ないのですが
#include <atomic>
#include <thread>
#include <iostream>
std::mutex m ;
int x ;
void thread()
{
std::lock_guard<std::mutex> guard(m) ;
++x ; // 非アトミック操作
}
int main()
{
x = 0 ; // 初期値0
std::thread A( thread ) ;
std::thread B( thread ) ;
A.join() ; B.join() ;
std::cout << x << std::endl ; // 2であるべき
}
本の虫: C++0xのマルチスレッドとデータ競合が非常に難しい手を加えてやる事でビルド出来る事が分かった。まずはオプションを上書きしてやる。
「バリアー!」「デュクシ!」「ちょっ、お前、オレ、バリアー張...
http://cpplover.blogspot.com/2011/06/c0x.html
#define _GLIBCXX_HAS_GTHREADS 1
#define _GLIBCXX__PTHREADS 1
#define _POSIX_TIMEOUTS 1
次に、gthreadsが内部処理の為に定義しているスレッド識別子による比較関数を定義する
#include <pthread.h>
inline bool
operator<(const pthread_t& lhs, const pthread_t& rhs) {
return lhs < rhs;
}
この状態でとりあえずコンパイルは出来る。ただしgthreads無効でビルドされているのでスレッド操作関数の実体が無い。そこでthread.ccからコードを拝借する。
namespace std
{
namespace
{
extern "C" void*
execute_native_thread_routine(void* __p)
{
thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p);
thread::__shared_base_type __local;
__local.swap(__t->_M_this_ptr);
__try
{
__t->_M_run();
}
__catch(...)
{
std::terminate();
}
return 0;
}
}
void
thread::_M_start_thread(__shared_base_type __b)
{
if (!__gthread_active_p())
__throw_system_error(int(errc::operation_not_permitted));
__b->_M_this_ptr = __b;
int __e = __gthread_create(&_M_id._M_thread,
&execute_native_thread_routine, __b.get());
if (__e)
{
__b->_M_this_ptr.reset();
__throw_system_error(__e);
}
}
void
thread::join()
{
int __e = EINVAL;
if (_M_id != id())
__e = __gthread_join(_M_id._M_thread, 0);
if (__e)
__throw_system_error(__e);
_M_id = id();
}
}
全体のソースだとこんな感じ。
// {{{
// vi:set ts=8 sts=2 sw=2 tw=0:
// vim:fdm=marker fdl=0 fdc=0 fdo+=jump,search:
// vim:fdt=substitute(getline(v\:foldstart),'\\(.\*\\){\\{3}','\\1',''):
#define _GLIBCXX_HAS_GTHREADS 1
#define _GLIBCXX__PTHREADS 1
#define _POSIX_TIMEOUTS 1
#include <pthread.h>
inline bool
operator<(const pthread_t& lhs, const pthread_t& rhs) {
return lhs < rhs;
}
// }}}
#include <atomic>
#include <thread>
#include <iostream>
// {{{
namespace std
{
namespace
{
extern "C" void*
execute_native_thread_routine(void* __p)
{
thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p);
thread::__shared_base_type __local;
__local.swap(__t->_M_this_ptr);
__try
{
__t->_M_run();
}
__catch(...)
{
std::terminate();
}
return 0;
}
}
void
thread::_M_start_thread(__shared_base_type __b)
{
if (!__gthread_active_p())
__throw_system_error(int(errc::operation_not_permitted));
__b->_M_this_ptr = __b;
int __e = __gthread_create(&_M_id._M_thread,
&execute_native_thread_routine, __b.get());
if (__e)
{
__b->_M_this_ptr.reset();
__throw_system_error(__e);
}
}
void
thread::join()
{
int __e = EINVAL;
if (_M_id != id())
__e = __gthread_join(_M_id._M_thread, 0);
if (__e)
__throw_system_error(__e);
_M_id = id();
}
}
// }}}
std::mutex m ;
int x ;
void thread()
{
std::lock_guard<std::mutex> guard(m) ;
++x ; // 非アトミック操作
}
int main()
{
x = 0 ; // 初期値0
std::thread A( thread ) ;
std::thread B( thread ) ;
A.join() ; B.join() ;
std::cout << x << std::endl ; // 2であるべき
}
これ、vimmerならfoldを使ってやれば
//
#include <atomic>
#include <thread>
#include <iostream>
//
int main() {
std::mutex m;
int x = 0;
std::thread A([&] {
for (int n = 0; n < 100; n++) {
std::lock_guard<std::mutex> guard(m);
++x;
std::cout << x << std::endl;
}
});
std::thread B([&] {
for (int n = 0; n < 100; n++) {
std::lock_guard<std::mutex> guard(m);
++x;
std::cout << x << std::endl;
}
});
A.join();
B.join();
}
こんな風に見えてちょっとはマシになる。これでmingw使ってthreadなプログラミングが出来ますね!lambda使えばこんなのも出来て、たのしーーーー!
#include <atomic>
#include <thread>
#include <iostream>
int main() {
std::mutex m;
int x = 0;
std::thread A([&] {
for (int n = 0; n < 100; n++) {
std::lock_guard<std::mutex> guard(m);
++x;
std::cout << x << std::endl;
}
});
std::thread B([&] {
for (int n = 0; n < 100; n++) {
std::lock_guard<std::mutex> guard(m);
++x;
std::cout << x << std::endl;
}
});
A.join();
B.join();
}
2011/06/24
GoogleAppEngineで動くGyazoサーバをGoで書いた。
Go言語フリークの皆さんこんばんわ。
テンポラリ的にキャプチャ画像をアップロードする際にはgyazoが一般的ですよね。僕もよく利用しています。
今日はこのgyazoに画像をアップロードするクライアントと、サーバを書きました。
タイトルページはGoogle WebFont APIを使ってなんなーくカッコいい感じにしてみました。ほんとになんとなーくです。
なお、クライアントはデフォルトではgyazo.comにアップロードしちゃうので
と書いた所で再度見たら、もうsubmitされてましたので、hg pullしてtipsにすると入ってます。
ちなみに、rack-1.3では先頭に空白行が入っていても正しく読める様な修正が入っている模様です。
テンポラリ的にキャプチャ画像をアップロードする際にはgyazoが一般的ですよね。僕もよく利用しています。
今日はこのgyazoに画像をアップロードするクライアントと、サーバを書きました。
mattn/gyago - GitHub
Gyazo application written in go
https://github.com/mattn/gyago
Gyagoコマンドラインで動くクライアントと、GoogleAppEngineで動くサーバです。クライアントはキャプチャ動作はしませんが、引数で与えたpngファイルをgyazoサーバにアップロード出来ます。またサーバはdatastoreを使って画像データをblobに格納する事でgyazoサーバを実現しています。
Gyazo on AppEngine
http://gyazo.compile-error.net/
タイトルページはGoogle WebFont APIを使ってなんなーくカッコいい感じにしてみました。ほんとになんとなーくです。
Google Web FontsGoogleAppEngineの無料枠なので、すぐMax Quotaになっちゃうかも知れませんが、良かったら遊んでみて下さい。
Google Web Fonts lets you browse all the fonts available via theGoogle Web Fonts API. All fonts in t...
http://www.google.com/webfonts
なお、クライアントはデフォルトではgyazo.comにアップロードしちゃうので
# gyago -e=http://gyazo.compile-error.net/ imagefile.png
という感じにアップロード先のエンドポイントを指定してあげて下さい。
ちなみに、sendさんがsinatraで書いたgyazoサーバにアップロードしたい場合は
# gyago -e=http://gyazo.send.sh/ imagefile.png
と指定すれば動きますが、現状のGoはmultipartの処理で、先頭に空白行が1行入る動作になっていて、rack-1.2と相性が悪い(先頭に空白行があるとマッチしない)ので、golang-devにパッチを投げてあります。と書いた所で再度見たら、もうsubmitされてましたので、hg pullしてtipsにすると入ってます。
ちなみに、rack-1.3では先頭に空白行が入っていても正しく読める様な修正が入っている模様です。