… | |
… | |
577 | } |
577 | } |
578 | } |
578 | } |
579 | |
579 | |
580 | static void end_thread (void) |
580 | static void end_thread (void) |
581 | { |
581 | { |
582 | bdb_req req; |
582 | bdb_req req = calloc (1, sizeof (bdb_cb)); |
583 | |
|
|
584 | Newz (0, req, 1, bdb_cb); |
|
|
585 | |
583 | |
586 | req->type = REQ_QUIT; |
584 | req->type = REQ_QUIT; |
587 | req->pri = PRI_MAX + PRI_BIAS; |
585 | req->pri = PRI_MAX + PRI_BIAS; |
588 | |
586 | |
589 | X_LOCK (reqlock); |
587 | X_LOCK (reqlock); |
… | |
… | |
714 | |
712 | |
715 | return count; |
713 | return count; |
716 | } |
714 | } |
717 | |
715 | |
718 | /*****************************************************************************/ |
716 | /*****************************************************************************/ |
|
|
717 | |
|
|
718 | static void |
|
|
719 | bdb_request (bdb_req req) |
|
|
720 | { |
|
|
721 | switch (req->type) |
|
|
722 | { |
|
|
723 | case REQ_ENV_OPEN: |
|
|
724 | req->result = req->env->open (req->env, req->buf1, req->uint1, req->int1); |
|
|
725 | break; |
|
|
726 | |
|
|
727 | case REQ_ENV_CLOSE: |
|
|
728 | req->result = req->env->close (req->env, req->uint1); |
|
|
729 | break; |
|
|
730 | |
|
|
731 | case REQ_ENV_TXN_CHECKPOINT: |
|
|
732 | req->result = req->env->txn_checkpoint (req->env, req->uint1, req->int1, req->uint2); |
|
|
733 | break; |
|
|
734 | |
|
|
735 | case REQ_ENV_LOCK_DETECT: |
|
|
736 | req->result = req->env->lock_detect (req->env, req->uint1, req->uint2, &req->int1); |
|
|
737 | break; |
|
|
738 | |
|
|
739 | case REQ_ENV_MEMP_SYNC: |
|
|
740 | req->result = req->env->memp_sync (req->env, 0); |
|
|
741 | break; |
|
|
742 | |
|
|
743 | case REQ_ENV_MEMP_TRICKLE: |
|
|
744 | req->result = req->env->memp_trickle (req->env, req->int1, &req->int2); |
|
|
745 | break; |
|
|
746 | |
|
|
747 | case REQ_ENV_DBREMOVE: |
|
|
748 | req->result = req->env->dbremove (req->env, req->txn, req->buf1, req->buf2, req->uint1); |
|
|
749 | break; |
|
|
750 | |
|
|
751 | case REQ_ENV_DBRENAME: |
|
|
752 | req->result = req->env->dbrename (req->env, req->txn, req->buf1, req->buf2, req->buf3, req->uint1); |
|
|
753 | break; |
|
|
754 | |
|
|
755 | case REQ_DB_OPEN: |
|
|
756 | req->result = req->db->open (req->db, req->txn, req->buf1, req->buf2, req->int1, req->uint1, req->int2); |
|
|
757 | break; |
|
|
758 | |
|
|
759 | case REQ_DB_CLOSE: |
|
|
760 | req->result = req->db->close (req->db, req->uint1); |
|
|
761 | break; |
|
|
762 | |
|
|
763 | #if DB_VERSION_MINOR >= 4 |
|
|
764 | case REQ_DB_COMPACT: |
|
|
765 | req->result = req->db->compact (req->db, req->txn, &req->dbt1, &req->dbt2, 0, req->uint1, 0); |
|
|
766 | break; |
|
|
767 | #endif |
|
|
768 | |
|
|
769 | case REQ_DB_SYNC: |
|
|
770 | req->result = req->db->sync (req->db, req->uint1); |
|
|
771 | break; |
|
|
772 | |
|
|
773 | case REQ_DB_UPGRADE: |
|
|
774 | req->result = req->db->upgrade (req->db, req->buf1, req->uint1); |
|
|
775 | break; |
|
|
776 | |
|
|
777 | case REQ_DB_PUT: |
|
|
778 | req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1); |
|
|
779 | break; |
|
|
780 | |
|
|
781 | #if DB_VERSION_MINOR >= 6 |
|
|
782 | case REQ_DB_EXISTS: |
|
|
783 | req->result = req->db->exists (req->db, req->txn, &req->dbt1, req->uint1); |
|
|
784 | break; |
|
|
785 | #endif |
|
|
786 | case REQ_DB_GET: |
|
|
787 | req->result = req->db->get (req->db, req->txn, &req->dbt1, &req->dbt3, req->uint1); |
|
|
788 | break; |
|
|
789 | |
|
|
790 | case REQ_DB_PGET: |
|
|
791 | req->result = req->db->pget (req->db, req->txn, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1); |
|
|
792 | break; |
|
|
793 | |
|
|
794 | case REQ_DB_DEL: |
|
|
795 | req->result = req->db->del (req->db, req->txn, &req->dbt1, req->uint1); |
|
|
796 | break; |
|
|
797 | |
|
|
798 | case REQ_DB_KEY_RANGE: |
|
|
799 | req->result = req->db->key_range (req->db, req->txn, &req->dbt1, &req->key_range, req->uint1); |
|
|
800 | break; |
|
|
801 | |
|
|
802 | case REQ_TXN_COMMIT: |
|
|
803 | req->result = req->txn->commit (req->txn, req->uint1); |
|
|
804 | break; |
|
|
805 | |
|
|
806 | case REQ_TXN_ABORT: |
|
|
807 | req->result = req->txn->abort (req->txn); |
|
|
808 | break; |
|
|
809 | |
|
|
810 | case REQ_TXN_FINISH: |
|
|
811 | if (req->txn->flags & TXN_DEADLOCK) |
|
|
812 | { |
|
|
813 | req->result = req->txn->abort (req->txn); |
|
|
814 | if (!req->result) |
|
|
815 | req->result = DB_LOCK_DEADLOCK; |
|
|
816 | } |
|
|
817 | else |
|
|
818 | req->result = req->txn->commit (req->txn, req->uint1); |
|
|
819 | break; |
|
|
820 | |
|
|
821 | case REQ_C_CLOSE: |
|
|
822 | req->result = req->dbc->c_close (req->dbc); |
|
|
823 | break; |
|
|
824 | |
|
|
825 | case REQ_C_COUNT: |
|
|
826 | { |
|
|
827 | db_recno_t recno; |
|
|
828 | req->result = req->dbc->c_count (req->dbc, &recno, req->uint1); |
|
|
829 | req->uv1 = recno; |
|
|
830 | } |
|
|
831 | break; |
|
|
832 | |
|
|
833 | case REQ_C_PUT: |
|
|
834 | req->result = req->dbc->c_put (req->dbc, &req->dbt1, &req->dbt2, req->uint1); |
|
|
835 | break; |
|
|
836 | |
|
|
837 | case REQ_C_GET: |
|
|
838 | req->result = req->dbc->c_get (req->dbc, &req->dbt1, &req->dbt3, req->uint1); |
|
|
839 | break; |
|
|
840 | |
|
|
841 | case REQ_C_PGET: |
|
|
842 | req->result = req->dbc->c_pget (req->dbc, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1); |
|
|
843 | break; |
|
|
844 | |
|
|
845 | case REQ_C_DEL: |
|
|
846 | req->result = req->dbc->c_del (req->dbc, req->uint1); |
|
|
847 | break; |
|
|
848 | |
|
|
849 | #if DB_VERSION_MINOR >= 3 |
|
|
850 | case REQ_SEQ_OPEN: |
|
|
851 | req->result = req->seq->open (req->seq, req->txn, &req->dbt1, req->uint1); |
|
|
852 | break; |
|
|
853 | |
|
|
854 | case REQ_SEQ_CLOSE: |
|
|
855 | req->result = req->seq->close (req->seq, req->uint1); |
|
|
856 | break; |
|
|
857 | |
|
|
858 | case REQ_SEQ_GET: |
|
|
859 | req->result = req->seq->get (req->seq, req->txn, req->int1, &req->seq_t, req->uint1); |
|
|
860 | break; |
|
|
861 | |
|
|
862 | case REQ_SEQ_REMOVE: |
|
|
863 | req->result = req->seq->remove (req->seq, req->txn, req->uint1); |
|
|
864 | break; |
|
|
865 | #endif |
|
|
866 | |
|
|
867 | default: |
|
|
868 | req->result = ENOSYS; |
|
|
869 | break; |
|
|
870 | } |
|
|
871 | |
|
|
872 | if (req->txn && (req->result > 0 || req->result == DB_LOCK_NOTGRANTED)) |
|
|
873 | req->txn->flags |= TXN_DEADLOCK; |
|
|
874 | } |
719 | |
875 | |
720 | X_THREAD_PROC (bdb_proc) |
876 | X_THREAD_PROC (bdb_proc) |
721 | { |
877 | { |
722 | bdb_req req; |
878 | bdb_req req; |
723 | struct timespec ts; |
879 | struct timespec ts; |
… | |
… | |
764 | |
920 | |
765 | --nready; |
921 | --nready; |
766 | |
922 | |
767 | X_UNLOCK (reqlock); |
923 | X_UNLOCK (reqlock); |
768 | |
924 | |
769 | switch (req->type) |
925 | if (req->type == REQ_QUIT) |
770 | { |
926 | { |
771 | case REQ_QUIT: |
927 | X_LOCK (reslock); |
772 | req->result = ENOSYS; |
928 | free (req); |
|
|
929 | self->req = 0; |
|
|
930 | X_UNLOCK (reslock); |
|
|
931 | |
773 | goto quit; |
932 | goto quit; |
774 | |
|
|
775 | case REQ_ENV_OPEN: |
|
|
776 | req->result = req->env->open (req->env, req->buf1, req->uint1, req->int1); |
|
|
777 | break; |
|
|
778 | |
|
|
779 | case REQ_ENV_CLOSE: |
|
|
780 | req->result = req->env->close (req->env, req->uint1); |
|
|
781 | break; |
|
|
782 | |
|
|
783 | case REQ_ENV_TXN_CHECKPOINT: |
|
|
784 | req->result = req->env->txn_checkpoint (req->env, req->uint1, req->int1, req->uint2); |
|
|
785 | break; |
|
|
786 | |
|
|
787 | case REQ_ENV_LOCK_DETECT: |
|
|
788 | req->result = req->env->lock_detect (req->env, req->uint1, req->uint2, &req->int1); |
|
|
789 | break; |
|
|
790 | |
|
|
791 | case REQ_ENV_MEMP_SYNC: |
|
|
792 | req->result = req->env->memp_sync (req->env, 0); |
|
|
793 | break; |
|
|
794 | |
|
|
795 | case REQ_ENV_MEMP_TRICKLE: |
|
|
796 | req->result = req->env->memp_trickle (req->env, req->int1, &req->int2); |
|
|
797 | break; |
|
|
798 | |
|
|
799 | case REQ_ENV_DBREMOVE: |
|
|
800 | req->result = req->env->dbremove (req->env, req->txn, req->buf1, req->buf2, req->uint1); |
|
|
801 | break; |
|
|
802 | |
|
|
803 | case REQ_ENV_DBRENAME: |
|
|
804 | req->result = req->env->dbrename (req->env, req->txn, req->buf1, req->buf2, req->buf3, req->uint1); |
|
|
805 | break; |
|
|
806 | |
|
|
807 | case REQ_DB_OPEN: |
|
|
808 | req->result = req->db->open (req->db, req->txn, req->buf1, req->buf2, req->int1, req->uint1, req->int2); |
|
|
809 | break; |
|
|
810 | |
|
|
811 | case REQ_DB_CLOSE: |
|
|
812 | req->result = req->db->close (req->db, req->uint1); |
|
|
813 | break; |
|
|
814 | |
|
|
815 | #if DB_VERSION_MINOR >= 4 |
|
|
816 | case REQ_DB_COMPACT: |
|
|
817 | req->result = req->db->compact (req->db, req->txn, &req->dbt1, &req->dbt2, 0, req->uint1, 0); |
|
|
818 | break; |
|
|
819 | #endif |
|
|
820 | |
|
|
821 | case REQ_DB_SYNC: |
|
|
822 | req->result = req->db->sync (req->db, req->uint1); |
|
|
823 | break; |
|
|
824 | |
|
|
825 | case REQ_DB_UPGRADE: |
|
|
826 | req->result = req->db->upgrade (req->db, req->buf1, req->uint1); |
|
|
827 | break; |
|
|
828 | |
|
|
829 | case REQ_DB_PUT: |
|
|
830 | req->result = req->db->put (req->db, req->txn, &req->dbt1, &req->dbt2, req->uint1); |
|
|
831 | break; |
|
|
832 | |
|
|
833 | #if DB_VERSION_MINOR >= 6 |
|
|
834 | case REQ_DB_EXISTS: |
|
|
835 | req->result = req->db->exists (req->db, req->txn, &req->dbt1, req->uint1); |
|
|
836 | break; |
|
|
837 | #endif |
|
|
838 | case REQ_DB_GET: |
|
|
839 | req->result = req->db->get (req->db, req->txn, &req->dbt1, &req->dbt3, req->uint1); |
|
|
840 | break; |
|
|
841 | |
|
|
842 | case REQ_DB_PGET: |
|
|
843 | req->result = req->db->pget (req->db, req->txn, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1); |
|
|
844 | break; |
|
|
845 | |
|
|
846 | case REQ_DB_DEL: |
|
|
847 | req->result = req->db->del (req->db, req->txn, &req->dbt1, req->uint1); |
|
|
848 | break; |
|
|
849 | |
|
|
850 | case REQ_DB_KEY_RANGE: |
|
|
851 | req->result = req->db->key_range (req->db, req->txn, &req->dbt1, &req->key_range, req->uint1); |
|
|
852 | break; |
|
|
853 | |
|
|
854 | case REQ_TXN_COMMIT: |
|
|
855 | req->result = req->txn->commit (req->txn, req->uint1); |
|
|
856 | break; |
|
|
857 | |
|
|
858 | case REQ_TXN_ABORT: |
|
|
859 | req->result = req->txn->abort (req->txn); |
|
|
860 | break; |
|
|
861 | |
|
|
862 | case REQ_TXN_FINISH: |
|
|
863 | if (req->txn->flags & TXN_DEADLOCK) |
|
|
864 | { |
|
|
865 | req->result = req->txn->abort (req->txn); |
|
|
866 | if (!req->result) |
|
|
867 | req->result = DB_LOCK_DEADLOCK; |
|
|
868 | } |
|
|
869 | else |
|
|
870 | req->result = req->txn->commit (req->txn, req->uint1); |
|
|
871 | break; |
|
|
872 | |
|
|
873 | case REQ_C_CLOSE: |
|
|
874 | req->result = req->dbc->c_close (req->dbc); |
|
|
875 | break; |
|
|
876 | |
|
|
877 | case REQ_C_COUNT: |
|
|
878 | { |
|
|
879 | db_recno_t recno; |
|
|
880 | req->result = req->dbc->c_count (req->dbc, &recno, req->uint1); |
|
|
881 | req->uv1 = recno; |
|
|
882 | } |
|
|
883 | break; |
|
|
884 | |
|
|
885 | case REQ_C_PUT: |
|
|
886 | req->result = req->dbc->c_put (req->dbc, &req->dbt1, &req->dbt2, req->uint1); |
|
|
887 | break; |
|
|
888 | |
|
|
889 | case REQ_C_GET: |
|
|
890 | req->result = req->dbc->c_get (req->dbc, &req->dbt1, &req->dbt3, req->uint1); |
|
|
891 | break; |
|
|
892 | |
|
|
893 | case REQ_C_PGET: |
|
|
894 | req->result = req->dbc->c_pget (req->dbc, &req->dbt1, &req->dbt2, &req->dbt3, req->uint1); |
|
|
895 | break; |
|
|
896 | |
|
|
897 | case REQ_C_DEL: |
|
|
898 | req->result = req->dbc->c_del (req->dbc, req->uint1); |
|
|
899 | break; |
|
|
900 | |
|
|
901 | #if DB_VERSION_MINOR >= 3 |
|
|
902 | case REQ_SEQ_OPEN: |
|
|
903 | req->result = req->seq->open (req->seq, req->txn, &req->dbt1, req->uint1); |
|
|
904 | break; |
|
|
905 | |
|
|
906 | case REQ_SEQ_CLOSE: |
|
|
907 | req->result = req->seq->close (req->seq, req->uint1); |
|
|
908 | break; |
|
|
909 | |
|
|
910 | case REQ_SEQ_GET: |
|
|
911 | req->result = req->seq->get (req->seq, req->txn, req->int1, &req->seq_t, req->uint1); |
|
|
912 | break; |
|
|
913 | |
|
|
914 | case REQ_SEQ_REMOVE: |
|
|
915 | req->result = req->seq->remove (req->seq, req->txn, req->uint1); |
|
|
916 | break; |
|
|
917 | #endif |
|
|
918 | |
|
|
919 | default: |
|
|
920 | req->result = ENOSYS; |
|
|
921 | break; |
|
|
922 | } |
933 | } |
923 | |
934 | |
924 | if (req->txn && (req->result > 0 || req->result == DB_LOCK_NOTGRANTED)) |
935 | bdb_request (req); |
925 | req->txn->flags |= TXN_DEADLOCK; |
|
|
926 | |
936 | |
927 | X_LOCK (reslock); |
937 | X_LOCK (reslock); |
928 | |
938 | |
929 | ++npending; |
939 | ++npending; |
930 | |
940 | |